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.
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:
- refuses a capability that was not granted, an origin not exactly declared, or a method not listed;
- strips any authorisation or cookie headers the document supplied;
- only then attaches the credential;
- does not follow redirects, so a permitted origin cannot bounce the request elsewhere;
- 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.
Consent that means something
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.