Security is critical for production workflows. This guide covers authentication, secrets management, encryption, access controls, and security best practices.
Authentication
API Key Management
Store API keys securely using Fibonacci’s keychain integration:
from fibonacci import SecureConfig
from fibonacci.security import KeychainStorage
# Store API key in system keychain
keychain = KeychainStorage()
keychain.set( "fibonacci_api_key" , "your-api-key" )
# Use in workflow
config = SecureConfig(
api_key = keychain.get( "fibonacci_api_key" )
)
Supported Keychain Backends
Platform Backend macOS Keychain Services Windows Windows Credential Manager Linux Secret Service (GNOME Keyring, KWallet)
Environment-Based Authentication
For CI/CD and containerized environments:
from fibonacci import SecureConfig
import os
config = SecureConfig(
api_key = os.environ.get( "FIBONACCI_API_KEY" ),
require_api_key = True
)
Secrets Management
Defining Secrets
Never hardcode secrets in workflow files:
# ❌ Bad - secrets in plain text
nodes :
- id : api_call
type : tool
tool : http.request
inputs :
headers :
Authorization : "Bearer sk-1234567890"
# ✅ Good - reference secrets
nodes :
- id : api_call
type : tool
tool : http.request
inputs :
headers :
Authorization : "Bearer {{secrets.API_KEY}}"
Setting Secrets via CLI
# Set a secret (prompts for value)
fibonacci secret set API_KEY
# Set secret for specific environment
fibonacci secret set API_KEY --env production
# List secrets (names only, never values)
fibonacci secret list
Secrets in Python
from fibonacci import Workflow
from fibonacci.security import SecretsManager
# Default: database backend
secrets = SecretsManager( backend = "db" )
# AWS Secrets Manager backend
# Requires: pip install boto3
# Env vars: SECRETS_BACKEND, AWS_REGION, AWS_SECRETS_PREFIX
secrets = SecretsManager(
backend = "aws_secrets_manager" ,
config = {
"region" : "us-east-1" ,
"prefix" : "fibonacci/prod" # optional
}
)
workflow = Workflow(
name = "secure-workflow" ,
secrets_manager = secrets
)
# Access secrets in code
api_key = secrets.get( "API_KEY" )
Secret Rotation
from fibonacci.security import SecretsManager, RotationPolicy
secrets = SecretsManager(
backend = "vault" ,
rotation_policy = RotationPolicy(
enabled = True ,
interval_days = 30 ,
notify_before_days = 7
)
)
# Check rotation status
status = secrets.rotation_status( "API_KEY" )
print ( f "Days until rotation: { status.days_remaining } " )
Production Environment Hardening
Required Settings
The server validates these settings at startup. Misconfigurations are fatal errors in APP_ENV=production and warnings in staging.
Variable Production Requirement Description SESSION_SECRET_KEYRequired (≥ 32 chars) Signing key for sessions TRUSTED_PROXY_HOSTSRecommended Comma-separated trusted proxy IPs ENABLE_DOCSMust be false Disables the interactive API docs UI ENABLE_DEVELOPER_ROUTESMust be false Disables developer-only routes
# Production .env
APP_ENV = production
SESSION_SECRET_KEY = your-random-secret-key-at-least-32-characters
TRUSTED_PROXY_HOSTS = 10.0.0.1,10.0.0.2
ENABLE_DOCS = false
ENABLE_DEVELOPER_ROUTES = false
Setting ENABLE_DOCS=true or ENABLE_DEVELOPER_ROUTES=true with APP_ENV=production prevents the server from starting . In staging these are warnings only.
Secrets Backend Configuration
Configure where Fibonacci stores organization secrets:
# Default: database
SECRETS_BACKEND = db
# AWS Secrets Manager
SECRETS_BACKEND = aws_secrets_manager
AWS_REGION = us-east-1
AWS_SECRETS_PREFIX = fibonacci/prod # optional namespace prefix
When SECRETS_BACKEND=aws_secrets_manager is set, boto3 must be installed — startup fails with a clear error if it is missing:
Secrets Health Endpoint
Verify secrets backend connectivity without exposing secret values:
{
"status" : "healthy" ,
"backend" : "aws_secrets_manager" ,
"checks" : {
"list_secrets" : "ok" ,
"get_secret" : "ok"
}
}
This endpoint confirms IAM connectivity only and never returns secret values. It requires ListSecrets and GetSecretValue IAM actions on the configured prefix.
Quota Override Validation
Quota overrides set by organization admins are validated to prevent abuse:
Negative or non-numeric values are silently discarded and replaced with the plan default.
Values exceeding 100× the plan default ceiling are rejected.
This prevents both DoS via zero/negative limits and rate-limit bypass via excessively large overrides. See Governance for how to set valid quota overrides.
Encryption
Data Encryption at Rest
Encrypt sensitive data stored in memory:
from fibonacci import Workflow, MemoryConfig
from fibonacci.security import EncryptionConfig
workflow = Workflow(
name = "encrypted-workflow" ,
memory_config = MemoryConfig(
backend = "redis" ,
encryption = EncryptionConfig(
enabled = True ,
algorithm = "AES-256-GCM" ,
key_source = "keychain" # or "env", "vault"
)
)
)
# All memory operations are now encrypted
workflow.memory.set( "sensitive_data" , { "ssn" : "123-45-6789" })
Encryption in Transit
All Fibonacci Cloud communications use TLS 1.3:
from fibonacci import FibonacciClient
client = FibonacciClient(
api_key = "..." ,
tls_config = {
"verify_certificates" : True ,
"min_version" : "1.3" ,
"client_cert" : "/path/to/cert.pem" , # mTLS
"client_key" : "/path/to/key.pem"
}
)
Field-Level Encryption
Encrypt specific fields in workflow data:
from fibonacci import LLMNode
from fibonacci.security import encrypt_field, decrypt_field
# Encrypt sensitive input before processing
encrypted_data = encrypt_field(
data = user_pii,
fields = [ "ssn" , "credit_card" ],
key_id = "pii-encryption-key"
)
# Decrypt when needed
decrypted = decrypt_field(
data = encrypted_data,
fields = [ "ssn" ],
key_id = "pii-encryption-key"
)
Access Control
Role-Based Access Control (RBAC)
Define roles and permissions for workflows:
from fibonacci import Workflow
from fibonacci.security import AccessControl, Role
# Define roles
admin_role = Role(
name = "admin" ,
permissions = [ "read" , "write" , "execute" , "delete" , "admin" ]
)
developer_role = Role(
name = "developer" ,
permissions = [ "read" , "write" , "execute" ]
)
viewer_role = Role(
name = "viewer" ,
permissions = [ "read" ]
)
workflow = Workflow(
name = "access-controlled" ,
access_control = AccessControl(
enabled = True ,
default_role = "viewer" ,
roles = [admin_role, developer_role, viewer_role]
)
)
Resource-Level Permissions
# fibonacci.yaml
access_control :
enabled : true
resources :
workflows :
"production/*" :
execute :
- role : admin
- role : production-deployer
write :
- role : admin
"development/*" :
execute :
- role : developer
- role : admin
write :
- role : developer
- role : admin
secrets :
"*" :
read :
- role : admin
write :
- role : admin
API Key Scopes
Create scoped API keys with limited permissions:
# Create read-only key
fibonacci auth create-key --name "monitoring" --scope read
# Create execution-only key
fibonacci auth create-key --name "ci-cd" --scope execute
# Create key with specific workflow access
fibonacci auth create-key --name "production" \
--scope execute \
--workflows "production/*"
API key scopes are returned by the API as a Dict[str, bool] map (e.g. {"runs:read": true, "runs:write": false}). The SDK’s APIKeyInfo.scopes field accepts both this dict form and the legacy list form.
Audit Logging
Enable Audit Logs
from fibonacci import Workflow
from fibonacci.security import AuditLogger
audit = AuditLogger(
enabled = True ,
destination = "cloudwatch" , # or "file", "splunk", "datadog"
config = {
"log_group" : "/fibonacci/audit" ,
"log_stream" : "workflows"
}
)
workflow = Workflow(
name = "audited-workflow" ,
audit_logger = audit
)
Audit Log Contents
Audit logs capture:
{
"timestamp" : "2025-01-23T10:30:00Z" ,
"event_type" : "workflow.execute" ,
"workflow_id" : "customer-support" ,
"user_id" : "user-123" ,
"ip_address" : "192.168.1.100" ,
"action" : "execute" ,
"status" : "success" ,
"duration_ms" : 1523 ,
"metadata" : {
"input_hash" : "abc123" ,
"nodes_executed" : [ "classifier" , "responder" ],
"api_key_id" : "key-456"
}
}
Additional audit events include DEVELOPER_SHELL_EXECUTED (emitted when a superuser accesses the developer shell), quota enforcement events, and governance setting changes.
Query Audit Logs
# View recent audit events
fibonacci audit logs --since "1 hour ago"
# Filter by workflow
fibonacci audit logs --workflow production-pipeline
# Filter by user
fibonacci audit logs --user user-123
# Export for analysis
fibonacci audit export --format json --output audit.json
For paginated API access to audit logs see the Governance guide .
Schema Validation
from fibonacci import Workflow
workflow = Workflow(
name = "validated-workflow" ,
input_schema = {
"type" : "object" ,
"required" : [ "user_input" ],
"properties" : {
"user_input" : {
"type" : "string" ,
"maxLength" : 10000 ,
"pattern" : "^[a-zA-Z0-9 \\ s.,!?-]*$"
},
"email" : {
"type" : "string" ,
"format" : "email"
}
},
"additionalProperties" : False
}
)
Prompt Injection Prevention
from fibonacci import LLMNode
from fibonacci.security import sanitize_input
# Sanitize user input before including in prompts
sanitized = sanitize_input(
user_input,
rules = [
"escape_xml" ,
"remove_system_prompts" ,
"limit_length"
]
)
node = LLMNode(
id = "analyzer" ,
model = "claude-sonnet-4-6" ,
prompt = f """Analyze this text:
<user_input>
{ sanitized }
</user_input>
Provide sentiment analysis.""" ,
prompt_injection_detection = True
)
Output Filtering
from fibonacci import Workflow
from fibonacci.security import OutputFilter
workflow = Workflow(
name = "filtered-workflow" ,
output_filter = OutputFilter(
rules = [
{ "type" : "pii" , "action" : "redact" },
{ "type" : "secrets" , "action" : "block" },
{ "type" : "code" , "action" : "sandbox" }
]
)
)
Network Security
IP Allowlisting
# fibonacci.yaml
security :
network :
ip_allowlist :
- 10.0.0.0/8
- 192.168.1.0/24
- 203.0.113.50
ip_blocklist :
- 0.0.0.0/0 # Block all except allowlist
VPC Configuration
from fibonacci import FibonacciClient
client = FibonacciClient(
api_key = "..." ,
vpc_config = {
"vpc_id" : "vpc-12345" ,
"subnet_ids" : [ "subnet-a" , "subnet-b" ],
"security_group_ids" : [ "sg-12345" ]
}
)
Security Checklist
Compliance
GDPR Compliance
from fibonacci import Workflow
from fibonacci.compliance import GDPRConfig
workflow = Workflow(
name = "gdpr-compliant" ,
compliance = GDPRConfig(
data_retention_days = 90 ,
enable_right_to_erasure = True ,
enable_data_portability = True ,
consent_tracking = True
)
)
SOC 2 Compliance
Fibonacci Cloud is SOC 2 Type II certified. Enable additional controls:
# fibonacci.yaml
compliance :
soc2 :
enabled : true
controls :
- access_logging
- encryption_at_rest
- encryption_in_transit
- vulnerability_scanning
- incident_response
Next Steps
Governance Organization governance, quotas, and policy administration
Best Practices Production workflow patterns