Verifiable cryptographic identity for AI agents, linked to human owners
via Alien Network SSO.
When an AI agent has an Alien Agent ID, every git commit it makes is SSH-signed and carries trailers that trace back
to the specific agent and the human who authorized it. The provenance chain is fully verifiable:
commit → agent key → SSO id_token (with cnf.jkt) → verified AlienID holder.
- How It Works
- Plugin Layout
- Quick Start (Claude Code)
- What a Signed Commit Looks Like
- Verifying Provenance
- Service Authentication
- Service Discovery
- Credential Vault
- Session Refresh
- Prerequisites
- Agent State
- CLI Reference
- Security
sequenceDiagram
participant Agent as AI Agent
participant SSO as Alien SSO
participant App as Alien App (Human)
Agent->>SSO: 1. Start OIDC auth, get QR / deep link
SSO->>App: 2. Human scans QR with Alien App
App->>SSO: 3. Human approves, callback to SSO
SSO->>Agent: 4. Exchange tokens, create cryptographic owner binding
Note over Agent: Alien Agent ID bound → SSH-signed git commits with provenance trailers
- Agent starts OIDC auth, gets a QR code / deep link
- Human scans QR with Alien App
- Human approves, Alien App calls back to SSO
- Agent exchanges tokens, creates cryptographic owner binding
The agent now has an Ed25519 keypair with a signed binding proving a verified human authorized it.
Alien Agent ID ships as a Claude Code plugin marketplace with six focused plugins. Each plugin has a narrow responsibility and depends on agent-id-core for the shared library + bootstrap surface:
| Plugin | Skill | What it does |
|---|---|---|
agent-id-core |
/agent-id-core |
Bootstrap (init / auth / bind / bootstrap), session lifecycle (refresh, status, setup-owner-session), and universal operations (sign, verify, export-proof). Owns the shared library that every other plugin imports: crypto primitives, the v3 bundle format + universal verifier (verifyBundle), SignatureEngine, OIDC, state I/O. |
agent-id-git |
/agent-id-git |
SSH-signed git commits with Agent-ID provenance trailers and v3 proof notes. setup, commit, verify. Verify calls into core's universal verifier and adds the SSH-signature + trailer checks on top — auditors and CI runners can verify any commit without a bound identity. |
agent-id-vault |
/agent-id-vault |
Portable encrypted credential vault for external-service secrets. Single file (vault.enc) with LUKS-style slots — agent-key (HKDF), passphrase (scrypt), mobile (phone), owner-approval (Alien app). Two one-way modes: user (default; no passphrase, app/agent-key unlock) and dev (--dev; passphrase allowed) — a user-mode vault can never gain a passphrase. Typed, domain-scoped credential records, including sealed in-vault-generated wallet keys (solana-keypair, evm-keypair). exec injects credentials into a child process's environment for env-var-auth CLIs/SDKs the proxy can't reach. init, add, generate, show, list, remove, exec, rekey, export, import, migrate. |
agent-id-proxy |
/agent-id-proxy |
Local credential-injecting HTTP proxy. Agent calls http://<proxy>/<credname>/<upstream-host>/<path>; proxy materializes the credential into the request by type and forwards over real HTTPS. Signs Solana/EVM transactions in-process for wallet credentials — the agent submits unsigned transactions. System CA bundle verifies upstream — no TLS interception, no local CA. Enforces per-credential host allowlist (default-deny). start, status, stop. |
agent-id-auth |
/agent-id-auth |
RFC 9449 DPoP-signed calls to Alien-aware services. header emits the two-header pair for one request; call is a one-shot signed HTTP request. discover fetches and validates /.well-known/alien-agent-id.json; capabilities renders the manifest as actionable markdown; support probes for the meta-tag support signal. |
agent-id-browser |
/agent-id-browser |
Universal browser the agent drives, with the logged-in profile sealed in the vault. One-time headed login establishes a session; afterwards the agent drives it headless — fine-grained control (accessibility snapshot + click/type/fill/select/press/navigate/screenshot/eval) plus one-shot read/fetch. For authenticated sites that block API/OAuth/cookie access (e.g. Gmail/Workspace). Bundles patchright (stealth Chrome); the agent never sees a credential. login, open, close, actions, read, fetch, status. |
Repository layout:
plugins/
├── agent-id-core/
│ ├── .claude-plugin/plugin.json
│ ├── lib/ # crypto, bundle, state, errors, oidc,
│ │ # signature-engine, cli-runtime
│ ├── bin/cli.mjs # 10 subcommands
│ ├── bin/qrcode.cjs # zero-dep terminal QR renderer
│ └── skills/agent-id-core/SKILL.md
├── agent-id-git/
│ ├── .claude-plugin/plugin.json
│ ├── bin/cli.mjs # setup, commit, verify
│ └── skills/agent-id-git/SKILL.md
├── agent-id-vault/
│ ├── .claude-plugin/plugin.json
│ ├── lib/format.mjs # Portable vault format + slot crypto
│ ├── lib/store.mjs # Typed credential schema + record CRUD
│ ├── lib/vault.mjs # Facade: open, init, export, import
│ ├── lib/trusted-input.mjs # /dev/tty channel for passphrases
│ ├── lib/legacy.mjs # v4 migration helpers
│ ├── bin/cli.mjs # init, add, show, list, remove, rekey,
│ │ # export, import, migrate
│ └── skills/agent-id-vault/SKILL.md
├── agent-id-proxy/
│ ├── lib/proxy.mjs # Server + URL-rewrite + stub injection
│ ├── lib/rewrite.mjs # URL-rewrite path: parse + materialize
│ ├── lib/stub.mjs # Legacy stub-injection helpers
│ ├── lib/totp.mjs # RFC 6238 TOTP generator
│ ├── bin/cli.mjs # start, status, stop
│ └── skills/agent-id-proxy/SKILL.md
├── agent-id-auth/
│ ├── .claude-plugin/plugin.json
│ ├── lib/manifest.mjs # /.well-known parser + validator
│ ├── bin/cli.mjs # header, call, discover, capabilities, support
│ └── skills/agent-id-auth/SKILL.md
└── agent-id-browser/
├── .claude-plugin/plugin.json
├── lib/launch.mjs # hardened patchright launch (sandbox on)
├── lib/profile-store.mjs # tar + AES-256-GCM seal of the profile (DEK in vault)
├── lib/session-server.mjs # persistent session + a11y snapshot/refs + actions
├── lib/unlock.mjs # owner-approval (Alien app) unlock
├── lib/session.mjs # logout detection
├── bin/cli.mjs # login, open/close, actions, read, fetch, status
├── package.json # bundles patchright (stealth Chrome)
└── skills/agent-id-browser/SKILL.md
.claude-plugin/marketplace.json # lists all six plugins
examples/ # demo-service.mjs, dev-sso.mjs
tests/ # unit + integration suites
docs/ # AGENT-SSO.md, INTEGRATION.md
Every plugin is zero npm dependencies (Node.js built-ins only) — except
agent-id-browser, which bundles patchright (a stealth Playwright) to drive a
real browser.
/plugin marketplace add alien-id/agent-id
/plugin install agent-id-core@alien-id-agent-id
/plugin install agent-id-git@alien-id-agent-id # for signed commits
/plugin install agent-id-vault@alien-id-agent-id # for credential storage
/plugin install agent-id-proxy@alien-id-agent-id # for credential injection at runtime
/plugin install agent-id-auth@alien-id-agent-id # for DPoP service calls
/plugin install agent-id-browser@alien-id-agent-id # for driving a logged-in browser
/reload-plugins
agent-id-core is required by every other plugin. agent-id-proxy depends on agent-id-vault. Install only what you need — auditors who just want to verify commits can install agent-id-core + agent-id-git and skip the rest.
If /reload-plugins does not pick up the new plugins on first run, restarting Claude Code usually helps.
/agent-id-core
Follow the instructions — the agent will generate a keypair, show a QR code, and wait for you to approve in the Alien App. Once done, your Alien Agent ID is created and bound.
/agent-id-git
The plugin writes the SSH key files and prints the public key. Add it to your GitHub account: GitHub → Settings → SSH and GPG keys → New SSH key → Key type: Signing Key. Commits will then show a "Verified" badge.
/agent-id-git stage, commit and push all files in the repo, follow the previous commits naming convention
Any agent with shell access can use the plugin CLIs directly. Requirements: Node.js 18+, git 2.34+, and permission to run node plugins/agent-id-<X>/bin/cli.mjs ... commands.
✓ Verified — This commit was signed with the committer's verified signature.
feat: implement auth flow
Agent-ID-JKT: wEf6o2ux8sBAUG4oQYhP284gfpZwUJMTxXDPH5XxthY
Agent-ID-Owner: 00000003010000000000539c741e0df8
Anyone can trace: this code → this agent (JKT) → this human (id_token sub)
→ verified AlienID holder.
Each commit also attaches a v3 proof bundle as a git note (refs/notes/agent-id) containing the SSO-signed id_token and the agent's public JWK — everything a verifier needs to prove the provenance chain without access to the agent's local state.
node plugins/agent-id-git/bin/cli.mjs verify --commit HEADVerification is self-contained: the v3 git-note bundle is { version: 3, id_token, agent_jwk }. Anyone who clones the repo and fetches the notes can verify the chain without access to the agent's machine.
# Fetch proof notes from remote
git fetch origin refs/notes/agent-id:refs/notes/agent-id
# Verify any commit
node plugins/agent-id-git/bin/cli.mjs verify --commit abc123flowchart LR
A[SSH commit signature] --> B[agent_jwk]
B --> C["id_token cnf.jkt"]
C --> D[SSO RS256 signature]
D --> E[Trailer JKT match]
- id_token signature — RS256 verified against Alien SSO's JWKS (
issmatches discovery) cnf.jktanchor — id_token's RFC 7800 §3.1 confirmation claim binds the SSO-attested owner to a specific Ed25519 key thumbprint- agent_jwk thumbprint — bundle's
agent_jwkthumbprint (RFC 7638) must equalcnf.jktand theAgent-ID-JKTtrailer - SSH commit signature — git's native SSH signature must verify against
agent_jwk
Steps 1–3 are the universal verification — they live in agent-id-core/lib/bundle.mjs as verifyBundle() and run against the bundle alone, without any git knowledge. Step 4 is the git-specific layer that agent-id-git adds on top. The same universal verifier can be called on any future v3 bundle (signed tool calls, exported proofs, …) without growing a git dependency.
Pre-v3 (legacy Agent-ID-Fingerprint / Agent-ID-Binding) commits are intentionally not supported. Their id_tokens predate the RFC 7800 cnf.jkt binding and cannot anchor the chain; see CHANGELOG.md for the 3.0.0 cutover notes.
Agents authenticate to Alien-aware services with RFC 9449 DPoP. The agent presents the SSO-issued access_token in the Authorization header and a fresh per-request proof JWT (signed by the agent's Ed25519 key) in the DPoP header.
The one-shot path: let the CLI sign and send the request for you.
node plugins/agent-id-auth/bin/cli.mjs call --url https://service.example.com/api/whoami
node plugins/agent-id-auth/bin/cli.mjs call --url https://service.example.com/api/posts \
--method POST --body-file ./body.jsonThe two-header path: emit the headers and drive the HTTP yourself.
node plugins/agent-id-auth/bin/cli.mjs header \
--url https://service.example.com/api/whoami --method GET --raw
# → Authorization: DPoP <access_token>
# → DPoP: <proof JWT>Each DPoP proof is single-use and request-bound: a fresh jti, current iat, and the htm/htu/ath claims bind the proof to one specific (method, URL, access_token) tuple. Reusing a proof on a different URL or with a different access token will be rejected.
Owner ↔ agent binding lives entirely in standard claims: the access_token carries sub (owner), aud, iss, and cnf.jkt (the agent key thumbprint, RFC 7800 §3.1). The DPoP proof binds the request to that same key per RFC 9449 §6.1. Services verify with @alien-id/sso-agent-id's verifyDPoPRequest — no custom envelope, no key registration.
Alien-aware services publish a JSON manifest at https://<host>/.well-known/alien-agent-id.json. Agents fetch and validate it before talking to the service.
node plugins/agent-id-auth/bin/cli.mjs discover --url https://example.comThe CLI enforces an 8 KiB body cap, rejects redirects, requires application/json, and validates against a closed schema (version, auth.header, auth.scheme, api.base, optional api.specUrl, optional service.name/service.url, optional api.operations[] for v2). Every URL in the manifest must share the same authority as the service URL the user gave the agent — see plugins/agent-id-auth/skills/agent-id-auth/SKILL.md for the full trust boundary. Same authority means host[:port] exactly, or a subdomain of it; no public-suffix-list expansion.
Services that publish an OpenAPI / JSON Schema document can declare it via api.specUrl, or can inline a closed-schema operations list via api.operations[] (manifest v2). To render the operations as actionable markdown:
node plugins/agent-id-auth/bin/cli.mjs capabilities --url https://example.comReplaces ALIEN-SKILL.md. Earlier 2.2.0 docs proposed a Markdown file (
ALIEN-SKILL.md) at the service root for the same purpose. That format is removed: free-form Markdown is too permissive a channel for a third-party server to feed an LLM. The well-known JSON manifest is the only supported discovery mechanism.
Services may also publish a closed-enum HTML meta tag advertising agent-id support:
<meta name="alien-agent-id" content="v1">The tag's content is a closed enum (v1, future versions) — no URLs, no prose. It exists so agents and crawlers can detect support without probing every host's /.well-known/. The manifest path is fixed; the meta tag never tells the agent where to go, only whether a service claims support. Probe it with:
node plugins/agent-id-auth/bin/cli.mjs support --url https://example.com
# → {"ok": true, "supported": true, "version": "v1"}The vault holds external-service credentials (GitHub PATs, OpenAI keys, Stripe secrets, cookies, TOTP seeds, …) in a single encrypted file at ~/.agent-id/vault.enc with a LUKS-style slot construction. The vault pairs with agent-id-proxy so the agent uses credentials by name without ever seeing the value.
Full details + architecture diagram: docs/VAULT-PROXY.md.
# 1. Initialize. Passphrase typed on /dev/tty — never enters the agent transcript.
node plugins/agent-id-vault/bin/cli.mjs init
# 2. Add credentials. Each one is typed and host-scoped (default-deny).
node plugins/agent-id-vault/bin/cli.mjs add --name github-pat --type bearer \
--domains '*.github.com,api.github.com' --value-file /tmp/tok
node plugins/agent-id-vault/bin/cli.mjs add --name openai-key --type header \
--header-name X-Api-Key --domains api.openai.com --value-env OPENAI_KEY
# 3. List metadata. Plaintext never appears.
node plugins/agent-id-vault/bin/cli.mjs list
# 4. Remove
node plugins/agent-id-vault/bin/cli.mjs remove --name github-patSupported credential types: bearer, basic, header, query, cookie, cookie-jar, totp, oauth2, solana-keypair, evm-keypair. Value-input channels — pick the smallest attack surface: --<field>-file, --<field>-env, piped stdin, raw --<field> arg (visible in ps; avoid). Never paste a secret into chat; transcripts persist.
For Solana and EVM (Ethereum, Polygon, Base, …) wallets the vault goes one step
further than storing a secret: it creates the private key itself and seals
it. The key never crosses a process boundary — generate prints only the
public address, show redacts, add refuses the type. The only way to use
the key is transaction signing inside the proxy, scoped to the credential's
RPC-host allowlist.
# Create wallets — output is the address, nothing else:
node plugins/agent-id-vault/bin/cli.mjs generate --name sol-hot \
--type solana-keypair --domains api.mainnet-beta.solana.com
node plugins/agent-id-vault/bin/cli.mjs generate --name polygon-hot \
--type evm-keypair --domains polygon-bor-rpc.publicnode.com
# The agent submits an UNSIGNED transaction through the proxy; the proxy signs:
curl http://localhost:48771/sol-hot/api.mainnet-beta.solana.com/ \
-d '{"jsonrpc":"2.0","id":1,"method":"sendTransaction",
"params":["<unsigned tx, base64>",{"encoding":"base64"}]}'
# EVM: eth_sendTransaction is rewritten to a signed eth_sendRawTransaction:
curl http://localhost:48771/polygon-hot/polygon-bor-rpc.publicnode.com/ \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_sendTransaction","params":[{
"to":"0x…","value":"0x38d7ea4c68000","chainId":137,"nonce":"0x0",
"gas":21000,"maxFeePerGas":120000000000,"maxPriorityFeePerGas":30000000000}]}'Solana signing handles legacy + v0 messages and preserves co-signatures
(partial signing — e.g. an x402 facilitator fee-payer). EVM signing produces
EIP-1559 transactions with RFC 6979 deterministic ECDSA. Both paths are
zero-dependency and verified end-to-end on Solana and Polygon mainnet — the
agent-side flow lives in
examples/solana-transfer-via-proxy.mjs.
The vault file is encrypted at rest — copy it to a second machine and import:
node plugins/agent-id-vault/bin/cli.mjs export --out vault.enc
# (copy vault.enc to machine B)
node plugins/agent-id-vault/bin/cli.mjs import --in vault.enc # asks for passphrase
node plugins/agent-id-vault/bin/cli.mjs rekey add-agent-key # bind B's agent for fast unlockOnce a credential is in the vault, the agent uses it through agent-id-proxy. The agent calls a local URL that names the credential and the upstream host; the proxy materializes the credential and forwards over real HTTPS:
# Start the proxy (default port 48771; tries agent-key unlock first, falls back to passphrase)
node plugins/agent-id-proxy/bin/cli.mjs start
# Agent calls a local URL — credname picks the credential, host validated by its allowlist
curl http://localhost:48771/github-pat/api.github.com/user
# → upstream sees `Authorization: Bearer ghp_xxx...`, agent transcript never saw the valueAfter --idle-timeout (default 12 h) the proxy zeroes the master key in memory; restart to re-unlock. See docs/VAULT-PROXY.md for the full request flow, threat model, and per-type materialization rules.
node plugins/agent-id-vault/bin/cli.mjs migrate --passphrase-file /tmp/passOne-shot: the old ~/.agent-id/vault/ directory is renamed to vault.bak/. Migrated records get the placeholder allowlist ["UNCONFIGURED.invalid"] — the proxy refuses to inject them until you attach real domains via agent-id-vault add.
After bootstrap, the agent receives SSO tokens including a refresh_token. The refresh command renews the access_token without requiring human interaction.
# Explicit refresh
node plugins/agent-id-core/bin/cli.mjs refresh
# Transparent — every per-plugin CLI internally calls SignatureEngine.ensureValidSession()
# before signing, so most consumers do not need to refresh explicitly.
node plugins/agent-id-auth/bin/cli.mjs header --url https://example.com/api/xIf the human revokes the agent's authorization via the Alien App, refresh surfaces auth-revoked and the agent will need to re-bootstrap.
- Node.js 18+ — uses built-in
crypto,fetch,fs(zero npm dependencies) - git 2.34+ — SSH commit signing support (only needed for
agent-id-git) - Alien App with a verified AlienID
- Provider address — registered in the Developer Portal (optional)
All state is stored in ~/.agent-id/ (configurable via --state-dir or AGENT_ID_STATE_DIR). The layout is the same regardless of which plugins you have installed — every plugin reads and writes through agent-id-core/lib/state.mjs.
~/.agent-id/
├── keys/main.json # Ed25519 keypair (mode 0600)
├── ssh/
│ ├── agent-id # SSH private key (mode 0600)
│ ├── agent-id.pub # SSH public key
│ └── allowed_signers # For git signature verification
├── vault.enc # Portable encrypted vault (mode 0600)
├── vault.bak/ # Legacy v4 per-credential dir, post-migration
├── proxy.json # Running-proxy state (pid, port, idleTimeoutMs)
├── proxy.log # JSONL access log — names only, never values or bodies
├── owner-session.json # SSO tokens — id_token IS the chain attestation (mode 0600)
├── nonces.json # Per-agent nonce tracking
├── sequence.json # Operation sequence counter
└── audit/operations.jsonl # Hash-chained signed operation log
Each plugin has its own CLI under plugins/agent-id-<NAME>/bin/cli.mjs. The common --state-dir <path> flag is accepted by every subcommand and defaults to AGENT_ID_STATE_DIR then ~/.agent-id.
| Command | Purpose |
|---|---|
bootstrap |
One-shot setup: init + auth + bind. Blocks ≤5 min while waiting for Alien App approval. |
init |
Generate the Ed25519 agent keypair. |
auth --provider-address <addr> |
Start OIDC authorization (emits deep-link + QR). |
bind [--timeout-sec N] |
Poll for approval, exchange tokens, verify cnf.jkt, persist owner-session.json. |
setup-owner-session |
Force a fresh OAuth flow against the existing keypair (used to migrate pre-v3 bindings). |
status |
Check whether an identity exists and is bound. |
refresh |
Refresh the SSO access_token + id_token (DPoP-bound). |
sign --type T --action A --payload JSON |
Sign an arbitrary operation into the audit trail. |
verify |
Chain-integrity check on the local audit trail. |
export-proof |
Emit the owner session + complete audit trail as JSON. |
| Command | Purpose |
|---|---|
setup |
Write the agent keypair into SSH-format files; print the public key to add to your git host. |
commit --message <M> [--push] [--remote R] [--allow-empty] |
Signed commit with Agent-ID-JKT / Agent-ID-Owner trailers + v3 proof note + audit-log entry. |
verify [--commit HASH] [--sso-url URL] |
Verify a commit's v3 attestation chain (universal verifyBundle + trailer + SSH-sig). |
See docs/VAULT-PROXY.md for the format + threat model. Full per-type flag reference is in the vault skill.
| Command | Purpose |
|---|---|
init [--passphrase-file F | --passphrase-env V] [--no-agent-key] |
Create the portable vault. Slot 0 = passphrase, slot 1 = agent-key (auto-added if a main key exists). |
add --name N --type T --domains H[,H…] [type-specific value flags] |
Add or replace a credential. Types: bearer, basic, header, query, cookie, cookie-jar, totp. Value-input flags: --<field>-file, --<field>-env, stdin, or raw --<field>. |
show --name N |
Retrieve plaintext. Prefer the proxy for runtime use — show is for manual export. |
list |
List metadata + slots (no plaintext). |
remove --name N |
Delete a record. |
exec --env VAR=cred.field [--env …] -- <cmd> |
Run <cmd> with credential fields injected into its environment (for env-var-auth CLIs/SDKs the proxy can't help with). Secret never touches disk, argv, or stdout; inherited stdio keeps interactive TTYs. |
rekey add-passphrase [--new-passphrase-file F] |
Append a passphrase slot. |
rekey add-agent-key |
Append an agent-key slot for fast unattended unlock on this machine. |
rekey remove-slot --id N |
Remove a slot (refuses to remove the last one). |
export --out PATH |
Copy the encrypted vault file. |
import --in PATH [--overwrite] |
Install an encrypted vault file. |
migrate [--passphrase-file F] [--default-domains H[,H…]] |
Convert legacy ~/.agent-id/vault/*.json → vault.enc. |
See docs/VAULT-PROXY.md for the URL-rewrite request flow and per-type materialization table.
| Command | Purpose |
|---|---|
start [--port N] [--host H] [--passphrase-file F | --passphrase-env V] [--no-agent-key] [--idle-timeout 12h|30m|never] |
Unlock the vault and listen on localhost. Default port 48771, default idle-lock 12h. Foreground (Ctrl-C exits). |
status |
JSON: running, pid, port, uptime, configured idleTimeout. |
stop |
SIGTERM the running proxy. |
Use it by calling http://<proxy>/<credname>/<upstream-host>/<path>. Legacy HTTP_PROXY + AgentVault <name> stub mode also works for plain-HTTP upstream.
| Command | Purpose |
|---|---|
header --url <U> [--method M] [--raw] |
Emit Authorization + DPoP headers for one request. |
call --url <U> [--method M] [--body S | --body-file F] [--content-type T] |
One-shot signed HTTP request (preferred). |
discover --url <U> |
Fetch + validate /.well-known/alien-agent-id.json. |
capabilities --url <U> |
Render a manifest's api.operations[] as actionable markdown. |
support --url <U> |
Probe a page for the <meta name="alien-agent-id"> support signal. |
Run any plugin's CLI with --help for the full flag list.
- Private keys stored with
0600permissions; state directories created with0700. - PKCE (S256) prevents authorization code interception (RFC 7636).
- SSO
id_token(RS256) commits the agent key thumbprint viacnf.jkt— the human ↔ agent binding lives inside the SSO-signed claim, not a separate self-signed envelope (RFC 7800 §3.1). - DPoP proof-of-possession (RFC 9449) — every service request carries a fresh Ed25519-signed proof bound to the URL, method, and
cnf.jkt; a leaked access_token is useless without the matching private key. - Hash-chained audit log — any tampering breaks the chain.
agent-id-core verifywalks it end-to-end. - Vault encryption — AES-256-GCM with HKDF-SHA256-derived key from agent's private key. Credentials are only readable on the same machine as the bound agent.
- JWT
alg: nonerejected — unsigned tokens are refused at parse level. - Subject validation — token refresh verifies the subject claim still matches the bound owner (
SubjectMismatchErroron mismatch). - Refresh tokens are sticky — bound to the original
cnf.jkt, no rotation needed. - Manifest validation — third-party manifests are parsed against a closed schema; same-authority guard refuses any URL that points outside the service's host or subdomain.
owner-session.jsoncontains tokens — never commit or share it.
- System Documentation — detailed SSO flow, credential storage, service auth
- Integration Guide — how to integrate token verification into your service
- Alien Network
- Developer Portal
