Documentation
¶
Overview ¶
Package token provides secure storage and retrieval of Linear API access tokens. It handles token persistence across sessions with proper encryption and file permissions to protect sensitive authentication credentials.
The package is designed to work seamlessly with the OAuth flow, storing tokens after successful authentication and providing them for API requests.
Token Storage ¶
Tokens are stored in a platform-specific secure location (XDG standard):
~/.config/linear/token
The token file has restricted permissions (0600) to prevent unauthorized access. Only the owner can read or write the token file.
Security Features ¶
- File permissions restricted to owner only (0600)
- Token validation before storage
- Automatic directory creation with proper permissions
- Safe file operations with atomic writes
- Clear error messages for permission issues
Usage ¶
Save a token after OAuth authentication:
storage := token.NewFileStorage()
err := storage.SaveToken("your-access-token")
if err != nil {
log.Fatal(err)
}
Retrieve a stored token:
token, err := storage.GetToken()
if err != nil {
if err == token.ErrTokenNotFound {
// Handle missing token - user needs to authenticate
}
log.Fatal(err)
}
Clear stored token on logout:
err := storage.ClearToken()
if err != nil {
log.Fatal(err)
}
Error Handling ¶
The package defines specific errors for common scenarios:
- ErrTokenNotFound: No token file exists (user not authenticated)
- ErrTokenEmpty: Token file exists but is empty
- Permission errors: Token file has incorrect permissions
- I/O errors: File system issues during read/write operations
Token Lifecycle ¶
1. Token Creation: OAuth flow generates access token 2. Token Storage: SaveToken() stores with secure permissions 3. Token Usage: GetToken() retrieves for API requests 4. Token Refresh: OAuth refresh flow updates stored token 5. Token Removal: ClearToken() removes on logout
Best Practices ¶
- Always check for ErrTokenNotFound to detect unauthenticated state
- Handle token refresh proactively before expiration
- Clear tokens on logout to maintain security
- Never log or display token values
- Validate tokens before storage to prevent corruption
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GetDefaultTokenPath ¶
func GetDefaultTokenPath() string
GetDefaultTokenPath returns the default path for storing tokens.
Token location strategy: - Primary: ~/.config/linear/token (XDG standard) - Fallback: .config/linear/token (current directory)
Why home directory: Tokens are user-specific credentials. Storing them in the home directory ensures they're not accidentally committed to version control and are isolated per user on multi-user systems.
func LoadTokenWithFallback ¶
func LoadTokenWithFallback() string
LoadTokenWithFallback loads token from default location with env var fallback
Types ¶
type Storage ¶
type Storage struct {
// contains filtered or unexported fields
}
Storage handles token storage and retrieval with secure file permissions. Tokens are sensitive credentials that must be protected from unauthorized access.
func NewStorage ¶
NewStorage creates a new token storage instance
func (*Storage) DeleteToken ¶
DeleteToken removes the token file
func (*Storage) SaveToken ¶
SaveToken saves a token to the file system with secure permissions.
Security measures: - Directory created with 0700 (owner only access) - Token file created with 0600 (owner read/write only) - Atomic write operation to prevent partial token storage
Why these permissions: OAuth tokens are bearer tokens - anyone with the token can act as the authenticated user. Restricting file permissions prevents other users on the system from reading the token.
func (*Storage) TokenExists
deprecated
TokenExists checks if a token file exists. Returns false for file not found and logs errors for other issues like permission denied.
Why log but not fail: This maintains backward compatibility while still alerting developers to potential issues. Permission errors might indicate security problems that should be investigated.
Deprecated: Use TokenExistsWithError for better error handling.
func (*Storage) TokenExistsWithError ¶
TokenExistsWithError checks if a token file exists and returns detailed error information. Returns (false, nil) if file doesn't exist - this is not an error condition. Returns (false, error) if there's an actual error like permission denied.
Why distinguish between "not found" and other errors: - File not found is expected when user hasn't authenticated yet - Permission errors indicate a security or configuration problem - This allows callers to handle these cases differently