User Story
As a developer, I want qctl to store my credentials in the OS keychain so I don't have tokens in plain text files and they're protected by my system's security.
Design
Command Interface
# Credentials are stored automatically on login
qctl auth login
# -> Stores token in macOS Keychain / Windows Credential Store / Linux secret-tool
# View credential storage location
qctl auth status
# -> Shows: "Credentials stored in: macOS Keychain"
# Configure storage backend
qctl config set auth.credential_store keychain # keychain | file | none
Keychain Entries
# macOS Keychain
Service: qctl
Account: voyage:access_token
Password: <token>
Service: qctl
Account: voyage:refresh_token
Password: <token>
# Windows Credential Store
Target: qctl:voyage:access_token
User: qctl
Password: <token>
# Linux secret-tool (libsecret)
Label: qctl voyage access_token
Attributes: application=qctl, provider=voyage, type=access_token
Secret: <token>
Fallback Strategy
1. Try OS keychain
2. If unavailable, fall back to encrypted file (~/.qctl/credentials.enc)
3. If encryption unavailable, warn and use plain file with strict permissions
Storage Configuration
# ~/.qctl/qctl.yaml
auth:
credential_store: keychain # keychain | file | memory
file_encryption: true # encrypt file-based storage
encryption_key_source: keychain # where to get encryption key
Files to Create/Modify
| File |
Action |
Purpose |
qctl-core/src/main/java/io/qrun/qctl/core/auth/CredentialStore.java |
Create |
Store interface |
qctl-core/src/main/java/io/qrun/qctl/core/auth/KeychainStore.java |
Create |
OS keychain implementation |
qctl-core/src/main/java/io/qrun/qctl/core/auth/MacOSKeychain.java |
Create |
macOS Keychain via Security.framework |
qctl-core/src/main/java/io/qrun/qctl/core/auth/WindowsCredStore.java |
Create |
Windows Credential Store |
qctl-core/src/main/java/io/qrun/qctl/core/auth/LinuxSecretService.java |
Create |
Linux libsecret/secret-tool |
qctl-core/src/main/java/io/qrun/qctl/core/auth/FileCredentialStore.java |
Create |
Encrypted file fallback |
qctl-core/src/main/java/io/qrun/qctl/core/auth/CredentialStoreFactory.java |
Create |
Platform detection |
Implementation Tasks
Acceptance Criteria
User Story
As a developer, I want qctl to store my credentials in the OS keychain so I don't have tokens in plain text files and they're protected by my system's security.
Design
Command Interface
Keychain Entries
Fallback Strategy
Storage Configuration
Files to Create/Modify
qctl-core/src/main/java/io/qrun/qctl/core/auth/CredentialStore.javaqctl-core/src/main/java/io/qrun/qctl/core/auth/KeychainStore.javaqctl-core/src/main/java/io/qrun/qctl/core/auth/MacOSKeychain.javaqctl-core/src/main/java/io/qrun/qctl/core/auth/WindowsCredStore.javaqctl-core/src/main/java/io/qrun/qctl/core/auth/LinuxSecretService.javaqctl-core/src/main/java/io/qrun/qctl/core/auth/FileCredentialStore.javaqctl-core/src/main/java/io/qrun/qctl/core/auth/CredentialStoreFactory.javaImplementation Tasks
Acceptance Criteria
qctl auth statusshows storage location