Make your first call
From "I have an API key" to "GitHub returned a real list of issues" in three curl commands.
You've connected GitHub, you have an App with an API key. Time to make a real call. We'll do it three times, each time getting a little less manual:
- Curl from the terminal — proves the platform works end-to-end with no SDK.
- TypeScript SDK — what your agent actually does in production.
- Look at the audit row — confirm every part of the call is in the chain.
1. Pick a policy
Without a policy, every authorize denies. Easiest fix: attach the
github:read-only starter template to your App.
- 1Open Policies
Policies → New policy → From template → github:read-only.
- 2Assign it to your App
Save the policy, then on the App's detail page set Default policy to the one you just created. Save.

One policy per App. Pick the read-only starter for now.
2. Curl an authorize
The control plane is at https://control.auto-nomos.com (or http://localhost:8788
for Docker). Ask for a UCAN that lets you list issues on a specific repo:
curl https://control.auto-nomos.com/v1/authorize \
-H "authorization: Bearer $NOMOS_API_KEY" \
-H "content-type: application/json" \
-d '{
"command": "/github/issue/list",
"resource": { "provider": "github", "owner": "acme", "repo": "app" },
"ttlSeconds": 300
}'
You'll get back:
{
"decision": "allow",
"ucan": "eyJhbGciOiJFZERTQSIsInR5cCI6Ikp…",
"receiptId": "evt_01J7K…",
"expiresAt": "2026-05-23T18:12:00.000Z"
}
The ucan field is your delegation. It's a JWT signed by your App's DID; the PDP will
recognize it on the next request.
If you get 'deny'
Your policy didn't permit that command. Open the audit page — every deny carries a
reason. The most common deny is policy_not_assigned (forgot to attach the policy
to the App) or command_not_permitted (the template doesn't include this command;
pick a broader template or write your own).
3. Curl the actual GitHub call
Now use that UCAN against the PDP. The PDP is at https://pdp.auto-nomos.com (or
http://localhost:8787 for Docker):
curl https://pdp.auto-nomos.com/github/issue/list \
-H "authorization: Bearer <paste UCAN from previous step>" \
-G --data-urlencode "owner=acme" --data-urlencode "repo=app"
The PDP validates the UCAN, decrypts your GitHub OAuth token, calls GitHub, and returns:
{
"issues": [
{ "number": 142, "title": "Audit chain corruption when…", "state": "open" },
{ "number": 141, "title": "RBAC: agent_manager can't…", "state": "open" }
]
}
That's it. Your agent now has the same capability — without the GitHub OAuth token ever existing in its process memory.
4. Do it from TypeScript
import { createIntentClient } from '@auto-nomos/sdk';
const client = createIntentClient({
controlPlaneUrl: process.env.NOMOS_CONTROL_URL!,
apiKey: process.env.NOMOS_API_KEY!,
});
const grant = await client.authorize({
command: '/github/issue/list',
resource: { provider: 'github', owner: 'acme', repo: 'app' },
ttlSeconds: 300,
});
if (grant.decision !== 'allow') {
throw new Error(`denied: ${grant.reason}`);
}
const response = await fetch(
'https://pdp.auto-nomos.com/github/issue/list?owner=acme&repo=app',
{ headers: { authorization: `Bearer ${grant.ucan}` } },
);
const data = await response.json();
console.log(data);
Same two HTTP calls, less plumbing. The SDK defaults to fail-closed — if the
control plane is unreachable, authorize() throws rather than letting your agent
fall through to "no auth check."
5. Look at the audit row
- 1Open Audit
Audit. Sort by newest. Your two calls (the authorize and the GitHub fetch) are the top two rows.

Every authorize and every PDP call is one row. Click for the full receipt. - 2Click the GitHub row
The drawer shows the full receipt: command, decision, resource, context, hash, prevHash, and a "Download proof" button. The hash chains to the previous row.
Verify it worked
- Audit shows
allowfor/github/issue/list, attributed to your App's DID. - Receipt drawer shows
prevHashmatching the row above. - "Download proof" gives you a JSON bundle that
@auto-nomos/audit-verifycan verify offline against your signed root.
You're done with Get Started
You've gone from zero to "agent has a working, audited, policy-gated GitHub delegation" — about 15 minutes. The next journey wires that into a real agent runtime.