Credentials Management
Purpose and Scope
This document describes the credential management system in Automatos AI, which provides secure storage, retrieval, and lifecycle management for sensitive credentials (API keys, database passwords, OAuth tokens, etc.). The system is inspired by n8n's credential architecture and provides encryption, testing, audit logging, and multi-environment support.
For information about authentication and workspace management, see Authentication Flow. For multi-tenancy and data isolation, see Data Isolation.
Sources: orchestrator/core/credentials/service.py:1-15, orchestrator/core/models/credentials.py:1-20
System Architecture
The credentials management system consists of four primary components:
Component Responsibilities:
CredentialType
Schema definitions for credential categories
Sources: orchestrator/core/credentials/service.py:42-56, orchestrator/core/models/credentials.py:25-131
Credential Types
Credential types define schemas for different categories of credentials (databases, APIs, OAuth providers). Each type specifies required fields, validation rules, and test endpoints.
Type Schema Structure
Credential Type Database Model:
id
Integer
Primary key
name
String(255)
Unique identifier (e.g., postgres_credentials)
display_name
String(255)
UI label (e.g., PostgreSQL)
category
String(100)
Category: database, ai, api, infrastructure
icon
String(50)
Icon name for UI
logo
String(255)
Logo file path
description
Text
Help text
schema_definition
JSON
Array of field definitions
test_endpoint
JSON
Test configuration
is_system
Boolean
System-defined vs user-created
is_active
Boolean
Enable/disable type
Sources: orchestrator/core/models/credentials.py:25-58
Field Type Definitions
Credential schemas support multiple field types with validation:
string
Plain text input
Host, username, database name
password
Masked input (encrypted)
Passwords, API keys
number
Numeric input
Port numbers, timeout values
boolean
True/false toggle
SSL enabled, verify certificates
options
Dropdown selection
Authentication method, region
hidden
Auto-populated (not shown)
Internal identifiers
Sources: orchestrator/core/models/credentials.py:137-145
Example: PostgreSQL Credential Type
Sources: orchestrator/core/credentials/service.py:598-623, orchestrator/core/models/credentials.py:146-167
Credential Storage
Credentials are stored in the credentials table with AES-256 encryption via Fernet. Each credential is workspace-scoped for multi-tenancy isolation.
Credential Data Model
Database Schema:
id
Integer
Primary Key
Unique identifier
name
String(255)
Not Null
User-friendly name
workspace_id
UUID
FK, Not Null, Cascade Delete
Workspace isolation
credential_type_id
Integer
FK, Not Null, Cascade Delete
Type definition
encrypted_data
Text
Not Null
Fernet-encrypted JSON blob
environment
String(50)
Default: production
Target environment
description
Text
Nullable
User notes
tags
JSON
Default: []
Organization tags
is_active
Boolean
Default: True
Active status
expires_at
DateTime
Nullable
Expiration timestamp
last_tested
DateTime
Nullable
Last test timestamp
test_status
String(50)
Nullable
Test result status
test_message
Text
Nullable
Test error message
created_by
String(255)
Nullable
Creator user ID
created_at
DateTime
Default: now()
Creation timestamp
updated_at
DateTime
Default: now(), Auto-update
Last update timestamp
Sources: orchestrator/core/models/credentials.py:60-103
Encryption System
The system uses Fernet (symmetric AES-256 encryption) via the cryptography library. All credential data is encrypted at rest.
Encryption Flow
EncryptionService Interface
Key Methods:
encrypt(plaintext: str) → str
Encrypt string
Returns base64-encoded ciphertext
decrypt(ciphertext: str) → str
Decrypt string
Returns plaintext
encrypt_dict(data: dict) → str
Encrypt JSON dict
Serializes then encrypts
decrypt_dict(ciphertext: str) → dict
Decrypt to dict
Decrypts then deserializes
Key Management:
The encryption key is loaded from environment variable ENCRYPTION_KEY. If not set, the system generates a new key on first use (development mode only).
⚠️ Production Deployment: The ENCRYPTION_KEY must be set in production. If the key is lost, encrypted credentials cannot be recovered.
Sources: orchestrator/core/credentials/encryption.py, orchestrator/core/credentials/service.py:143-148
Credential Operations
The CredentialStore class provides comprehensive CRUD operations with encryption, validation, and audit logging.
Create Credential Flow
Implementation Reference:
Key Validation Steps:
Type Validation: Ensure
credential_type_idexistsSchema Validation: Check required fields against type schema
Duplicate Check: Prevent duplicate names in same environment
Field Type Validation: Validate number/boolean types
Encryption: Encrypt entire credential data dict
Sources: orchestrator/core/credentials/service.py:99-182
Get Decrypted Credential
Accessing decrypted credentials requires explicit security checks and audit logging:
Security Checks:
Credential not found
Raise CredentialNotFoundError
is_active == False
Create audit log, raise error
expires_at < now()
Create audit log, raise error
Decryption fails
Create audit log, raise EncryptionKeyError
Audit Context: All access is logged with user_id, ip_address, service_name, and fields_accessed.
Sources: orchestrator/core/credentials/service.py:378-464
Update Credential
Updates support partial modification with automatic re-encryption:
Tracked Changes:
namechange: Old vs new namecredential_datachange: Marked as 'updated' (no plaintext logged)description,tags,is_active,expires_at: Old vs new values
Sources: orchestrator/core/credentials/service.py:238-314
Delete Credential
Deletion follows a secure erase pattern:
Secure Deletion Steps:
Create audit log before deletion (preserved in database)
Overwrite
encrypted_datawith encrypted "DELETED" stringFlush to database
Execute
DELETEusing raw SQL to avoid SQLAlchemy relationship loadingDatabase CASCADE automatically deletes associated audit logs
Sources: orchestrator/core/credentials/service.py:316-372
Credential Testing
The CredentialTester validates credentials by performing actual connections or API calls.
Testing Flow
Test Implementation: PostgreSQL
Supported Test Types:
postgres_credentials
Database connection
psycopg2.connect() with 5s timeout
redis_credentials
Cache ping
redis.Redis.ping() with 5s timeout
API credentials
HTTP call
httpx.AsyncClient.get() with 10s timeout
OAuth tokens
Token presence
Check access_token field exists
Test Result Storage:
After testing, the credential record is updated:
last_tested: Current timestamptest_status:'passed'or'failed'test_message: Success message or error details
Sources: orchestrator/core/credentials/service.py:504-656
Audit Logging
All credential operations are logged to credential_audit_logs for security auditing and compliance.
Audit Log Schema
Logged Actions:
created
New credential
credential_type, environment
updated
Modify credential
changes (old vs new values)
deleted
Delete credential
credential_name
accessed
Decrypt credential
service, fields_accessed
access_denied
Auth failure
reason (inactive, expired)
access_failed
Decrypt failure
Error message
tested
Test credential
test_result details
Query Audit Logs:
Sources: orchestrator/core/credentials/service.py:790-848, orchestrator/core/models/credentials.py:105-131
Environment Management
Credentials support multi-environment deployment with environment-scoped storage.
Environment Isolation
Environment Resolution:
When retrieving credentials by name:
MVP Note: The current implementation is environment-agnostic for single-environment deployments. Full multi-environment support can be enabled by uncommenting environment filtering.
Sources: orchestrator/core/credentials/service.py:187-199
Security Considerations
Encryption Key Management
⚠️ Critical Security Requirements:
Set
ENCRYPTION_KEYin Production:Generate:
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"Store in environment variable or secrets manager
Never commit to version control
Key Rotation Strategy:
Current implementation does not support key rotation
Rotating keys requires re-encrypting all credentials
Plan migration strategy before rotating
Backup Considerations:
Database backups include encrypted credentials
Backups are useless without the encryption key
Store key separately from database backups
Sources: orchestrator/config.py, .gitignore:99-105
Access Control
Credential Access Patterns:
Direct Access (Decryption):
Requires workspace-level access
All access is audit-logged
Checks
is_activeandexpires_at
Service Access:
Services use
get_decrypted_credential()withservice_nameAudit log captures service identity
Supports credential-by-name resolution
Test Access:
Testing temporarily decrypts credentials
Results stored in credential record
Audit log tracks test attempts
Sources: orchestrator/core/credentials/service.py:378-464
Data Validation
Input Validation:
Schema Validation:
Required fields checked
Type validation (number, boolean)
Custom validation rules from schema
Duplicate Prevention:
Unique constraint on (name, environment)
Only active credentials checked
Prevents accidental overwrites
Expiration Enforcement:
Checked on every access
Expired credentials rejected
Audit log records rejection
Sources: orchestrator/core/credentials/service.py:725-781
Audit Trail
Compliance Features:
Complete Access Trail:
Who accessed credentials
When accessed
From what IP address
Which fields accessed
Change Tracking:
All modifications logged
Old vs new values (except encrypted data)
Deletion audit preserved
Test Results:
Test success/failure logged
Error messages captured
Test frequency tracked
Retention: Audit logs are cascaded deleted with credentials but can be archived before deletion if needed.
Sources: orchestrator/core/credentials/service.py:790-813
Configuration Reference
Environment Variables
ENCRYPTION_KEY
String
None
Fernet encryption key (32 bytes, base64)
POSTGRES_DB
String
Required
Database name
POSTGRES_USER
String
Required
Database user
POSTGRES_PASSWORD
String
Required
Database password
POSTGRES_HOST
String
Required
Database host
POSTGRES_PORT
String
5432
Database port
Example Configuration:
Sources: orchestrator/config.py:36-43, orchestrator/.env.example:1-11
API Endpoints
Credential CRUD
GET
/api/credentials/types
List credential types
Yes
GET
/api/credentials/types/{id}
Get credential type
Yes
GET
/api/credentials
List credentials
Yes
GET
/api/credentials/{id}
Get credential details
Yes
POST
/api/credentials
Create credential
Yes
PUT
/api/credentials/{id}
Update credential
Yes
DELETE
/api/credentials/{id}
Delete credential
Yes
POST
/api/credentials/{id}/test
Test credential
Yes
GET
/api/credentials/{id}/audit-logs
Get audit logs
Yes
Note: Actual API endpoints may be implemented in a credentials router that is not included in the provided files. The CredentialStore service is designed to support these operations.
Sources: orchestrator/core/credentials/service.py, orchestrator/core/models/credentials.py:246-342
Usage Examples
Creating a Credential
Accessing Decrypted Credentials
Testing a Credential
Sources: orchestrator/core/credentials/service.py:99-182, orchestrator/core/credentials/service.py:378-464, orchestrator/core/credentials/service.py:504-562
Last updated

