Developer documentation
Developer portal
Last reviewed 31 August 2026
All docs
cainstudio.online/portal — and the same portal on the self-hosted deployment at /portal.
An engineering control centre for the Trust Fabric. One page, no build step, no framework: it loads in a single request, and you can read the whole of it with view-source and check that the panels really call the endpoints they claim to.
The rule this portal is built on#
> Every interactive panel names the real endpoint it calls. A panel with no > backing endpoint is declared planned and rendered as a stub.
That is enforced, not intended. portal.validate() cross-checks every live panel's declared endpoints against the deployment's real OpenAPI document during sync.sh, and the build fails if one is missing. It caught three real mismatches the first time it ran.
Panels are labelled:
| status | meaning |
live | calls the endpoints it declares, shows real data |
local | runs entirely in your browser, sends nothing anywhere |
planned | not built — rendered as a stub that says so |
There is currently 1 planned panel (a live event stream). There is no streaming endpoint yet, and polling once a second dressed up as "live" would be a lie about the architecture.
The portal is governed by CAIN#
Consequential developer actions — publishing an extension, rotating a key, revoking a principal, changing policy, exporting evidence — are routed through the real decision path before they happen:
POST /portal/actions/publish_extension
VERDICT: ALLOWED | decision_id: fd_a4003572107e46aba05f930a identity allow enforcing authorization allow enforcing policy allow enforcing risk allow enforcing actionproof skipped enforcing
That decision is real evidence. It is retrievable, signed (HMAC-SHA256 over 8 fields), and reading it is itself recorded in the evidence access log.
Two deliberate properties:
- It authorizes; it does not act. The endpoint answers "may I" and returns the
decision id. A single call that both decides and acts is one where you could never prove afterwards that the check ran.
- It fails closed. If the control plane is unreachable it returns 503, never
an approval. An unknown action returns 404 with the list of known ones — it does not silently allow.
If CAIN cannot govern its own control surface, it cannot govern anything.
Roles#
Ten roles, each a lens over the same platform — not ten products. Each carries its own learning path, the APIs it actually touches, the conformance suites that matter to it, and a project template.
| role | you are |
| AI Application Developer | protecting an agent you already have |
| CAIN Integration Developer | wiring CAIN into a framework or platform |
| MCP Developer | governing tool calls on an MCP server |
| Trust / Policy Engineer | deciding what agents may do, provably |
| CAIN Security Engineer | trying to break it first |
| Verification / ActionProof Developer | proving plans before they run |
| Evidence / Observability Developer | making what happened findable later |
| Extension / Marketplace Developer | building for other people to install |
| Platform / Infrastructure Engineer | running it |
| Enterprise / Deployment Engineer | deciding whether it can go in your company |
Your role selection persists locally. Your credential does not — see below.
Panels#
Trust Decision Explorer · submit an action, watch the real stage-by-stage path ActionProof Debugger · submit a plan; reports not_configured honestly when there is no profile Evidence Explorer · decisions, signatures, and who read what Agent Run Viewer · one correlated run, and what a shadow deployment would have refused Policy Playground · dry runs with no enforcement and no side effects Security Lab · real injection payloads through the risk screen — including a benign control, because a screen that flags everything is not a screen Conformance · live posture per stage, including stages enforcing with nothing loaded System Status / Metrics · the same data cain doctor reads Marketplace / Extension Publisher · browse, claim a handle, authorize a publish MCP Inspector · list tools over real MCP Integration Generator · local — a template, not a code model Trust Surface · the eleven domains with their published coverage gaps Executable Quickstart · progress checked against the API
Your credential#
The portal asks for an API key and holds it in that tab's memory only. Not localStorage: an injected script can read localStorage, and this is a full-privilege credential. The cost is retyping after a refresh, which is the right trade for a surface that governs production.
Every panel calls the same authenticated APIs your agents call. There is no privileged back channel — anything the portal shows you, you can reproduce with curl.
Onboarding#
Ten steps: create account → create project → install CLI → connect agent/MCP → run first trust decision → inspect evidence → pass conformance → build extension → publish → deploy.
5 of 10 are checked against the real API. The other 5 cannot be verified from a browser — whether cain.yaml is on your disk, whether the CLI is installed, whether cain test passed — and they are drawn with a dashed border and say why. Showing an unverifiable step as complete would make the whole progress display worthless.
Community#
Discord · GitHub · vulnerability reporting (safe harbour, real response target) · changelog · what we don't do yet · roadmap.
Named as not built, rather than quietly omitted: a forum (Discord covers it; a dead forum is worse than none), a certification programme (cain test is the conformance check — a certificate implies an assessor and there isn't one), and a paid bug bounty (reporters are credited instead).