Toolcog enables AI to execute API operations using your credentials. This is inherently sensitive. We designed the system from the ground up to minimize what can go wrong and limit the blast radius when something does.
This document describes the security architecture. It’s intended for technical decision-makers evaluating whether Toolcog meets their security requirements.
When AI calls APIs on behalf of users, several things can go wrong:
Our architecture addresses each of these threats through structural guarantees—properties of the system design that hold regardless of configuration or operator behavior.
User credentials are protected by four-tier envelope encryption. The encryption keys are derived from authentication tokens that only the user possesses. We cannot decrypt stored credentials—even with full database access.
The key hierarchy:
To decrypt a credential, you need the user’s auth token to derive the KEK to unwrap the DEK to decrypt the credential. Without the token, the chain cannot begin.
Credentials exist in plaintext only during the execution of an API operation. They’re decrypted, applied to the request, and immediately discarded. They never appear in logs, never persist in memory pools, never enter AI conversation context.
Each login session creates its own cryptographic vault. When you create an API key or authorize an MCP client, the new grant automatically inherits your session’s vault—the vault DEK is wrapped for the new grant’s KEK and passed through the authorization flow.
For sessions created independently (different browsers, different devices), X25519 key escrow enables vault unification after the fact. The initiating session wraps its vault DEK using an ECDH-derived key that only the target session can compute. Each escrow uses a fresh key derivation, providing forward secrecy. Escrows expire after 24 hours. When the target claims the escrow, credentials in its old vault are re-encrypted with the shared vault’s DEK—nothing is lost.
Vault access is tied to session lifetime. When sessions expire or are revoked, vault access expires with them. Orphaned vaults become permanently inaccessible—this is acceptable because credentials can be reauthorized.
We analyzed 4,138 OpenAPI specifications from public sources. Only 39% properly declare security schemes. The majority embed authentication as regular header parameters, creating ambiguity about what constitutes a credential.
Toolcog normalizes these specifications automatically. When we detect authentication headers declared as parameters (Authorization, X-API-Key, and variants), we promote them to proper security schemes. This ensures consistent credential handling regardless of how the original spec was authored.
We maintain approximately 100,000 lines of JSON Schema and OpenAPI processing code. This isn’t a wrapper around existing libraries—it’s a purpose-built compiler stack that gives us complete control over how specifications are parsed, validated, and transformed.
The stack supports all major schema dialects (JSON Schema Draft 2020-12, Draft 07, Draft 05, OpenAPI 3.0, OpenAPI 3.1) with full reference resolution, tree-shaking, and type generation. Every transformation preserves semantic correctness. Malformed input fails loudly rather than being silently misinterpreted.
This investment exists because security depends on faithful specification handling. If the system misunderstands what an API expects, credentials could be sent incorrectly or user input could end up in unintended places.
API requests are constructed through declarative template expansion, not string concatenation. URL paths use RFC 6570 URI templates with hygienic variable expansion. Parameters are encoded according to their OpenAPI definitions using type-aware encoders.
User input flows through structured transformers that understand the target context. A value destined for a query parameter is encoded differently than one destined for a JSON body. The encoding is determined by the specification, not by the shape of the input.
This makes injection structurally difficult. There’s no point in the pipeline where raw user input is concatenated with trusted strings. Every value passes through context-appropriate encoding before reaching the final request.
Credentials are bound to security schemes by name. The request execution layer only applies a credential to an operation that explicitly declares that security scheme. Even if you have valid credentials stored, they cannot be applied to operations that don’t request them.
This prevents credential leakage across APIs. Your Stripe credentials cannot accidentally flow to a GitHub request, even if both are configured in your vault. The binding is enforced at the HTTP layer during request construction.
The authentication service has zero third-party runtime dependencies. Every cryptographic operation uses WebCrypto primitives. Every data structure is implemented directly.
This eliminates supply chain attack surface in the most sensitive part of the system. There are no transitive dependencies to audit, no upstream maintainers to trust, no dependency confusion attacks to worry about.
Service-to-service requests use the same token-based authentication as user requests. Internal services authenticate with service tokens—encrypted envelopes with service identifiers as subjects.
Even routes that aren’t publicly accessible require valid service tokens. This provides defense in depth: network segmentation failures don’t automatically grant access to internal operations.
Resources are protected by a capability-based permission system. Permissions are granted per-resource, per-operation, per-subject. There are no ambient authorities—every action requires explicit permission.
Permission checks use a priority-ordered evaluation: specific resource permissions take precedence over account-level defaults, specific operations take precedence over wildcards, direct user grants take precedence over group membership.
Services that manage resources on behalf of users receive only the permissions explicitly granted. Hub can manage an API you created because you granted it permission when you created the API—not because it has blanket access to all resources.
We don’t send credentials to AI models. When AI discovers and executes API operations, it provides operation names and parameters. The system resolves credentials from your vault and applies them at the HTTP layer. The AI never sees your API keys or OAuth tokens.
We don’t log credential values. Audit logs record which operations were executed with which security schemes, but never the credential contents.
We don’t store plaintext keys. The server holds one symmetric key (SERVER_KEY) used for token encryption. All other key material is derived or wrapped.
We don’t trust API specifications blindly. Specifications are normalized, validated, and processed through a compiler stack that rejects ambiguous or malformed input.
No system is perfectly secure. Our architecture minimizes attack surface and limits blast radius, but it doesn’t eliminate all risk.
If your auth token is compromised, an attacker can access your credentials for the duration of that session. Token lifetimes are bounded, and tokens can be revoked, but the window exists.
If an API specification is intentionally malicious and crafted to evade our normalization, it might be possible to construct requests that behave unexpectedly. Our normalization covers known patterns from real-world analysis, but novel attack vectors could exist.
If WebCrypto or the underlying platform has vulnerabilities, our cryptographic guarantees depend on those being sound. We use standard primitives (AES-GCM, AES-KW, HKDF, X25519) with no custom cryptography.
Security concerns should be reported to security@toolcog.com.
For vulnerability reports, include sufficient detail to reproduce the issue. We’ll acknowledge receipt within 24 hours and provide an initial assessment within 72 hours.