Design note

Secrets that never enter the file

How IDOP lets a document call an API with the user's key without ever seeing the key — credential bindings, origin pinning and the reader as broker.

IDOP LABS2 min read

Secure executionConsent and capabilities

A document that calls an external service needs a credential. The obvious design — let the document hold the key, or ask the user to paste it into the document — is the one IDOP rules out. A file is copied, emailed, archived and shared. Anything inside it will eventually be seen by someone it was not meant for.

The binding names a need, not a service

In IDOP 1.0 a manifest declares a credential binding: { id, required, description? }. It names no provider and contains no secret. A network capability that needs a credential refers to the binding by id, alongside the exact HTTPS origins and methods it will use:

"requiredCapabilities": [{
  "id": "ai", "type": "network",
  "origins": ["https://api.example.com"], "methods": ["POST"],
  "credentialBinding": "api-key", "purpose": "Generate answers"
}],
"credentialBindings": [{ "id": "api-key", "required": true }]

The reader holds the key — and its limits

The user stores a credential in the reader, and the user decides which origins that credential may be sent to. A binding is satisfied only by a credential whose allowed origins cover every origin of every capability that uses it. The manifest can narrow where a credential travels; it can never widen it (§12.2).

When the document calls idop.network.request, the reader:

  1. refuses a capability that was not granted, an origin not exactly declared, or a method not listed;
  2. strips any authorisation or cookie headers the document supplied;
  3. only then attaches the credential;
  4. does not follow redirects, so a permitted origin cannot bounce the request elsewhere;
  5. counts the request against a finite per-session budget, so an approved document cannot spend a user’s paid credit in a loop.

The document receives the response — status, a limited set of headers, and a text body. It never receives the key, and there is deliberately no API that returns one.

Before a document runs, the user is shown, for each capability, which credential would travel to which origins, and for what declared purpose. “Allow for this version” is remembered against a digest of the application, its version, all of its code and its declared capabilities. If any of those change, the approval no longer applies.

What this does not solve

A granted capability is real access. If you allow a document to call a service with your key, it can do whatever that service permits within the declared origins and methods. The design makes the grant explicit, narrow and revocable; it cannot make an unwise grant safe.