Paperclip AI Secrets Management and Injection into Agent Runs: Implementation Guide
Paperclip AI encrypts and stores secrets centrally in the company_secrets table, then injects them into agent runs via environment variables or on-demand API calls while maintaining zero-knowledge security and comprehensive audit logging.
Paperclip AI provides a robust secrets management system designed to handle sensitive credentials for AI agent operations. The platform supports both company-scoped and user-scoped secrets, offering flexible storage options ranging from local encryption to external vaults like AWS Secrets Manager. Understanding how Paperclip manages secrets and injects them into agent runs is essential for deploying secure, production-ready AI workflows.
Architecture Overview
The secrets management system in Paperclip AI is built around three distinct layers that handle storage, external provider integration, and runtime injection.
Secret Storage Layer
At the core, encrypted values persist in the company_secrets table. Secrets are scoped either to a company (shared across the organization) or to a user (personal credentials). The encryption logic and CRUD operations reside in [server/src/services/secrets.ts](https://github.com/paperclipai/paperclip/blob/master/server/src/services/secrets.ts), which handles creation, rotation, and resolution.
Provider Vaults
Secrets can be managed by external vaults or stored locally. The secret_provider_configs table stores non-sensitive configuration (regions, KMS keys, endpoints) while the actual credentials remain in the external system. The provider registry in [server/src/secrets/provider-registry.js](https://github.com/paperclipai/paperclip/blob/master/server/src/secrets/provider-registry.js) maps provider names like aws_secrets_manager or local_encrypted to their runtime implementations.
Agent Injection Layer
When an agent starts, Paperclip resolves any secret_ref or user_secret_ref entries in the adapter configuration. The injection logic in [server/src/services/tool-gateway.ts](https://github.com/paperclipai/paperclip/blob/master/server/src/services/tool-gateway.ts) decrypts values and places them into the agent's environment or returns them via secure API endpoints.
Company vs. User Secrets
Paperclip distinguishes between two secret scopes with different resolution paths.
Company secrets are owned by the organization and referenced directly by secretId in adapter configurations. They suit static credentials shared across teams, such as organization-wide API keys.
User secrets are defined per-user and referenced by a definition key rather than a concrete ID. The UI renders these with a distinct violet accent. In [server/src/services/secrets.ts](https://github.com/paperclipai/paperclip/blob/master/server/src/services/secrets.ts), the resolution logic validates that user-scoped secrets must be resolved through user secret declarations, ensuring personal credentials never bleed across user boundaries.
The Secret Lifecycle
Managing secrets in Paperclip follows a five-stage pipeline from creation to audit.
1. Creation
Board users create secrets via POST /api/companies/{companyId}/secrets. The payload supports two modes:
- Inline values: Encrypted immediately and stored locally
- External references: Store only the ARN or pointer to an external vault entry
curl -X POST https://localhost:3100/api/companies/123/secrets \
-H "Authorization: Bearer <board-token>" \
-H "Content-Type: application/json" \
-d '{
"name": "anthropic-api-key",
"value": "sk-ant-..."
}'
2. Vault Configuration
External vaults are registered via /api/companies/{companyId}/secret-provider-configs. The configuration contains connectivity parameters but never receives raw credentials. Health checks at /api/companies/{companyId}/secret-providers/health verify runtime connectivity without exposing secrets.
3. Binding
Adapter configs reference secrets using typed descriptors:
{
"env": {
"ANTHROPIC_API_KEY": {
"type": "secret_ref",
"secretId": "c8b2f5e1-7a4d-4b9a-9f2e-1d5d3a7f6c9b",
"version": "latest"
},
"GITHUB_TOKEN": {
"type": "user_secret_ref",
"key": "github_api_token",
"version": "latest",
"required": true
}
}
}
4. Runtime Resolution
When the agent heartbeat starts, Paperclip:
- Looks up the secret ID or user definition in
company_secrets - If the secret is managed (
provider != "local_encrypted"), calls the provider SDK (e.g., AWS SDK) to fetch plaintext - Decrypts locally stored values using the configured encryption key
- Injects the value into
process.envor returns it via the API
5. Auditing
Every fetch creates entries in secret_access_events and activity_log. No secret value is ever logged or returned to the UI. API responses omit value fields entirely, and the UI provides no "reveal" button.
Injection Paths
Paperclip offers two mechanisms for making secrets available to agents, chosen based on access patterns and security requirements.
Environment Injection
Use environment injection when adapters need secrets on every run, such as API tokens for external services. The secret is resolved once per heartbeat and placed into the agent's environment variables.
This approach minimizes latency for frequently accessed credentials but places the secret in the agent's memory space for the duration of the run.
On-Demand Fetch
For large payloads, occasional access, or when adapters do not inherit the environment, agents call:
curl -X POST https://localhost:3100/api/agents/me/secrets/ANTHROPIC_API_KEY/value \
-H "Authorization: Bearer <run-bound-agent-jwt>"
The server resolves the secret, returns it with Cache-Control: no-store, and logs the access. This method keeps sensitive data out of the environment unless explicitly needed.
Security Guarantees
Paperclip implements several safeguards to protect sensitive data:
- Zero-knowledge architecture: Provider credentials and secret plaintext never leave the runtime boundary
- Response redaction: All API responses exclude
valuefields; the UI never displays decrypted content - Custody boundaries: Once injected into an agent process, the agent can read the secret, so custody ends at injection. Operators should follow the deployment guide for detailed custody rules
- Versioned rotation: Secrets support versioning; rotating a secret via
POST /api/secrets/{id}/rotatecreates a new version while maintaining backward compatibility for pinned references
Remote Import Workflow
Paperclip can link existing external vault entries without copying values into its database:
- Preview:
POST /api/companies/{companyId}/secrets/remote-import/previewlists candidate external references - Import:
POST /api/companies/{companyId}/secrets/remote-importcreates secrets withmanagedMode: "external_reference", storing only the ARN and fingerprint
This workflow is ideal for organizations that already manage secrets in AWS Secrets Manager or similar systems.
Code Examples
Creating an External-Reference Secret
curl -X POST https://localhost:3100/api/companies/123/secrets \
-H "Authorization: Bearer <board-token>" \
-H "Content-Type: application/json" \
-d '{
"name": "prod-stripe-key",
"provider": "aws_secrets_manager",
"managedMode": "external_reference",
"externalRef": "arn:aws:secretsmanager:us-east-1:123456789012:secret:paperclip/prod/stripe"
}'
Rotating a Secret
curl -X POST https://localhost:3100/api/secrets/c8b2f5e1-7a4d-4b9a-9f2e-1d5d3a7f6c9b/rotate \
-H "Authorization: Bearer <board-token>" \
-H "Content-Type: application/json" \
-d '{"value":"sk-ant-new-value..."}'
The new version becomes the default for any version: "latest" bindings.
Summary
- Paperclip AI secrets management centers on the
company_secretstable with encryption at rest and support for external vaults viasecret_provider_configs - Two scopes exist: company secrets (referenced by ID) and user secrets (referenced by definition key), with resolution logic in
server/src/services/secrets.ts - Dual injection methods: Environment variables for frequent access, on-demand API calls for occasional or large payloads
- Comprehensive audit trail via
secret_access_eventsensures no secret access goes unlogged - Zero-knowledge design ensures plaintext values never appear in logs, UI, or API responses outside the agent runtime
Frequently Asked Questions
How does Paperclip AI encrypt secrets at rest?
Secrets stored locally use the local_encrypted provider, which encrypts values before persistence in the company_secrets table. The encryption keys are managed separately from the application database. For external vaults, Paperclip stores only references (ARNs or fingerprints), keeping the actual encryption and storage within the external provider's infrastructure.
What is the difference between secret_ref and user_secret_ref in agent configurations?
A secret_ref references a company-scoped secret by its UUID (secretId), making it suitable for shared organizational credentials. A user_secret_ref uses a definition key (key) to lookup user-specific secrets, ensuring that each agent run accesses the credentials belonging to the specific user who triggered the run. The UI distinguishes user secrets with a violet accent indicator.
How do agents access secrets during runtime?
Agents receive secrets through one of two paths: environment injection, where Paperclip resolves secrets during the heartbeat and populates process.env before the agent code executes, or on-demand fetching, where the agent calls POST /api/agents/me/secrets/<key>/value to retrieve specific values via HTTPS with Cache-Control: no-store headers.
Can Paperclip AI integrate with existing AWS Secrets Manager vaults?
Yes. Through the remote import workflow, operators can preview and import existing AWS Secrets Manager entries without copying values into Paperclip. The system creates external_reference secrets that store only the ARN and metadata. At runtime, Paperclip calls the AWS SDK to fetch plaintext values dynamically, maintaining a single source of truth for credentials.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →