Skip to content

Conversation

@LaberionAjvazi
Copy link
Contributor

@LaberionAjvazi LaberionAjvazi commented Jan 8, 2026

Description

Implemented secure secret storage using keytar lib with fallback to the current plain text storage for cases where storing the secrets in the system keychain fails or is not available (eg. on linux due to libsecret dependency).

A warning will be shown to users when creating or using a profile with insecure secret storage.

Solutions for migrating existing profile secrets automatically or providing a helper command will be considered separately.

Relevant links

Checklist

  • I have self-reviewed this PR
  • I have tested the change and proved that it works in different scenarios
  • I have updated docs if needed

Note

Introduces secure storage for profile secrets with automatic use of the system keychain and plaintext fallback when unavailable.

  • New SecureSecretStorageService using keytar to save/retrieve apiToken, clientSecret, and refreshToken under celonis-content-cli:<profile-name>
  • Profile model updated (ProfileSecrets, secretsStoredSecurely flag); storeProfile now async, strips secrets when saved securely; findProfile loads secrets from keychain when flagged
  • ProfileCommandService/ProfileService updated to await storeProfile and persist refreshed tokens securely
  • Documentation expanded with security behavior, storage locations, and best practices
  • package.json adds keytar; extensive unit tests added for secure storage, fallback, and keytar-unavailable scenarios; lockfile updated

Written by Cursor Bugbot for commit 9c60ea8. This will update automatically on new commits. Configure here.

@LaberionAjvazi LaberionAjvazi marked this pull request as ready for review January 8, 2026 17:29
@LaberionAjvazi LaberionAjvazi requested a review from a team as a code owner January 8, 2026 17:29

**Best Practices:**
- Ensure your system keychain is properly configured and accessible
- If you see warnings about plaintext storage, consider re-creating the profile to enable secure storage
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see you mentioned a migration solution being intentionally skipped in the PR description, but I think it would be very straightforward to enable users on it without re-create. Something like content-cli profile secure <profile> and re-use logic the already implemented logic from this PR.

@@ -1,3 +1,3 @@
{
"name": "@celonis/content-cli",
"version": "1.4.1",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes probably deserve a major release

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's decide that after merging and testing.

Buqeta
Buqeta previously approved these changes Jan 9, 2026
}
}

export const secureSecretStorageService = new SecureSecretStorageService(); No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This diverges from the Content CLI structure of services. Can we change to an injectable class?


if (!secretsStoredInKeychain) {
logger.warn("⚠️ Failed to store secrets securely. They will be stored in plain text file.");
return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is the best approach. Maybe we should just give a message that storing failed, and then propose to the non-recommended storage, which can be an option in the command. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be a breaking change and can affect automated scripts that use content-cli. The implemented approach graciously fails and falls back to the insecure secret storage, and is a pattern that is commonly used by cli tools - especially those using keytar.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Jan 9, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

5 participants