CAIN-42 CAIN Studio

Developer documentation

Troubleshooting

Last reviewed 31 August 2026

All docs

Start here, with only the SDK installed:

curl -s https://cainstudio.online/fabric/identity/whoami -H "X-API-Key: $CAIN_API_KEY"
cainstudio decisions               # 401 = no key sent; 402 = the key is unknown, revoked or its plan is inactive (the message says which)
cainstudio explain <decision-id>   # which stage decided, and why

On a self-hosted MCPGate, cain doctor names the misconfiguration and prints the command that fixes it.

> cain is the operator CLI that ships with self-hosted MCPGate; it is not installable on its own yet (CLI reference). With only the SDK, use cainstudio or plain curl (see the quickstart).

"not authenticated" / exit code 4#

export CAIN_API_KEY=...            # the key from /signup; an agent uses its own agt_... key

If it still fails, the key may be valid but the subscription inactive -- that returns HTTP 402 and doctor reports it separately from a rejected key.

"could not reach the fabric" / exit code 3#

cain status
cain connect --endpoint https://cainstudio.online

Exit code 3 is deliberately distinct from 1: an outage is not a policy refusal. When the fabric is unreachable every decision is ERROR, and under strict mode that means every guarded call refuses. That is intended -- a network failure between an agent and its authorization service is not consent.

Everything is allowed and I expected denials#

Likely one of three things, all of which cain doctor reports:

1. The deployment is in shadow mode. Decisions are recorded, nothing blocks. Check cain status for mode. 2. The stage you expected to block is advisory. cain status lists which stages are enforcing. 3. The stage is enforcing but has nothing loaded. doctor reports patterns_loaded: 0 for exactly this case -- enforcing with nothing to match.

Nothing is allowed#

  • policy.default: deny with no rules that permit your action. cain policy test

will tell you.

  • A revoked principal. cain doctor reports principal status.
  • The fabric is unreachable and strict mode is on -- see above.

UNKNOWN verdicts#

A stage could not answer. cain explain <id> names it. Common cause: the ActionProof or agent-id service is down; doctor checks dependency reachability.

UNKNOWN is refused rather than allowed by design. If you need the looser behaviour, enforcement.strict: false is the switch -- and doctor will warn about it for as long as it is off, because it converts "we could not check" into permission.

cain validate fails on a key I am sure exists#

Unknown keys are errors, not warnings. Run cain validate --list-keys for the accepted set. This is deliberate: a typo'd key that gets silently ignored is how a config ends up looking stricter than it is.

"MCP calls are not being decided"#

Your client is probably still reaching the server directly. Putting the gateway in the path does not remove the direct route -- bind the server to localhost or a network only the gateway can reach. cain doctor cannot detect this and does not claim to.

The signature changed between reads#

It should not; signing is deterministic. If it did, the decision record was altered, which is the property the signature exists to reveal. `cain test --suite evidence` checks this explicitly.