{"id":49284770,"url":"https://github.com/p-vbordei/agent-id","last_synced_at":"2026-04-25T21:00:56.122Z","repository":{"id":353743384,"uuid":"1220723617","full_name":"p-vbordei/agent-id","owner":"p-vbordei","description":"Machine-first identity for AI agents. Self-custody DID + Capability VC profile. ~400 LOC, 5 deps, no blockchain.","archived":false,"fork":false,"pushed_at":"2026-04-25T09:09:10.000Z","size":82,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-25T11:12:27.631Z","etag":null,"topics":["agent-infrastructure","ai-agents","bun","decentralized-identity","did","did-key","did-web","ed25519","eddsa-jcs-2022","self-custody","typescript","verifiable-credentials"],"latest_commit_sha":null,"homepage":"https://github.com/p-vbordei/agent-id","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/p-vbordei.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-25T08:42:58.000Z","updated_at":"2026-04-25T09:09:20.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/p-vbordei/agent-id","commit_stats":null,"previous_names":["p-vbordei/agent-id"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/p-vbordei/agent-id","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-vbordei%2Fagent-id","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-vbordei%2Fagent-id/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-vbordei%2Fagent-id/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-vbordei%2Fagent-id/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/p-vbordei","download_url":"https://codeload.github.com/p-vbordei/agent-id/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p-vbordei%2Fagent-id/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32276628,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T18:29:39.964Z","status":"ssl_error","status_checked_at":"2026-04-25T18:29:32.149Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-infrastructure","ai-agents","bun","decentralized-identity","did","did-key","did-web","ed25519","eddsa-jcs-2022","self-custody","typescript","verifiable-credentials"],"created_at":"2026-04-25T21:00:38.133Z","updated_at":"2026-04-25T21:00:56.115Z","avatar_url":"https://github.com/p-vbordei.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# agent-id\n\n[![CI](https://github.com/p-vbordei/agent-id/actions/workflows/ci.yml/badge.svg)](https://github.com/p-vbordei/agent-id/actions/workflows/ci.yml)\n[![Spec v1.0](https://img.shields.io/badge/spec-v1.0-blue)](./SPEC.md)\n[![License](https://img.shields.io/badge/license-Apache%202.0-green)](./LICENSE)\n[![Bun](https://img.shields.io/badge/runtime-bun-fbf0df)](https://bun.sh)\n\n\u003e **Machine-first identity for AI agents.** Self-custody DID + Capability Verifiable Credential profile. Three functions, five dependencies, zero blockchain.\n\n```typescript\nimport { generateKeyPair, didKeyFromPublicKey, issue, verify } from 'agent-id'\n\nconst principal = await generateKeyPair()\nconst agent = await generateKeyPair()\n\nconst vc = await issue({\n  principal,\n  subject: {\n    id: didKeyFromPublicKey(agent.publicKey),\n    type: 'Agent',\n    principal: didKeyFromPublicKey(principal.publicKey),\n    model: { vendor: 'anthropic', id: 'claude-opus-4-7' },\n    capability: { action: 'answer', sla: { latency_ms_p95: 2000 } },\n    valid_from: new Date().toISOString(),\n  },\n})\n\nconst { verified } = await verify(vc) // true\n```\n\nThat's the whole story: a principal signs a capability claim about an agent, anyone can verify it, no central authority involved.\n\n---\n\n## Why agent-id\n\nEvery AI agent eventually needs to answer four questions to anyone it talks to:\n\n1. **Who am I?** (a stable, verifiable identity)\n2. **Who controls me?** (the principal — human, org, or parent agent)\n3. **What can I do?** (capability — action + scope + SLA)\n4. **Which model am I running?** (vendor, model id, optionally a fingerprint)\n\nThe W3C primitives that make this possible — DIDs, Verifiable Credentials, Ed25519 signatures, JSON-LD — have been mature for years. What's been missing is the **agent-native profile on top**: a canonical `@context`, a JSON Schema for `{ model, principal, capability, sla }`, and a conformance suite that any implementation can run.\n\n`agent-id` is that profile. ~400 LOC of TypeScript composing audited primitives. Read the [SPEC](./SPEC.md) in 5 minutes.\n\n---\n\n## Quickstart (30 seconds)\n\n```bash\ngit clone https://github.com/p-vbordei/agent-id.git\ncd agent-id\nbun install\nbun run examples/demo.ts\n```\n\nYou'll see a principal and an agent exchange a signed Capability VC. Signature verified, schema validated, DIDs resolved.\n\n**Use as a library:**\n\n```bash\nbun add github:p-vbordei/agent-id          # until npm publish\n# or, eventually:\nbun add agent-id\n```\n\n---\n\n## What you get\n\n| Artifact | Path | What it is |\n|---|---|---|\n| Library | [`src/`](./src) | TypeScript reference impl, 3 public functions |\n| Spec | [`SPEC.md`](./SPEC.md) | v1.0, normative — pin this in your project |\n| JSON-LD context | [`context/v1.jsonld`](./context/v1.jsonld) | Term definitions for the VC |\n| JSON Schema | [`schema/capability-v1.json`](./schema/capability-v1.json) | 2020-12, validates the credential shape |\n| Conformance | [`conformance/`](./conformance) | 3 test vectors (C1 / C2 / C3) + runner |\n| Demo | [`examples/demo.ts`](./examples/demo.ts) | 18 lines, full value prop |\n\n---\n\n## API\n\nThree functions, no classes, no factories.\n\n### `issue(opts) → Promise\u003cVerifiableCredential\u003e`\n\nMints a Capability VC signed with `eddsa-jcs-2022`.\n\n```typescript\nconst vc = await issue({\n  principal,                          // KeyPair (the signer)\n  subject: { id, type, principal, model, capability, valid_from },\n  validFrom?, validUntil?,            // defaults: now / never\n  now?,                               // for deterministic tests\n  issuer?, verificationMethod?,       // override for did:web principals\n})\n```\n\n### `verify(vc, opts?) → Promise\u003c{ verified, errors }\u003e`\n\nChecks: schema → validity window (±5 min skew) → signature → agent-DID resolution. Errors accumulate; you see all problems at once.\n\n```typescript\nconst { verified, errors } = await verify(vc, {\n  now?,                               // defaults to new Date()\n  fetch?,                             // for did:web — inject a stub or use global\n  skewSeconds?,                       // defaults to 300\n})\n```\n\n### `resolve(did, opts?) → Promise\u003cDidDocument\u003e`\n\nAlgorithmic for `did:key` (no network). HTTP fetch for `did:web`.\n\n```typescript\nconst doc = await resolve('did:key:z6Mk...')\nconst doc = await resolve('did:web:example.com', { fetch })\n```\n\nPlus three small helpers exported for convenience: `generateKeyPair`, `didKeyFromPublicKey`, `publicKeyFromDidKey`.\n\n---\n\n## When to use this\n\n- You're building an AI agent and need a verifiable identity for it.\n- You want self-custody — no central registry, no platform vendor lock-in.\n- You need *machine* identity, not human identity (no UI, no consent flows).\n- You want to bind a capability claim to a model + principal in one signed object.\n- You're a service that wants to verify \"is this agent allowed to do X?\" before responding.\n\n## When NOT to use this\n\n- You need TLS-anchored identity → use Google A2A's signed Agent Cards.\n- You want a generic VC framework → use [`@digitalbazaar/vc`](https://github.com/digitalbazaar/vc) or [SpruceID](https://github.com/spruceid/ssi).\n- You want a wallet UI for humans → use Veramo, Trinsic, or similar.\n- You want tool / function descriptions → use [MCP](https://modelcontextprotocol.io/), `agent-id` describes WHO the agent is, not WHAT functions it has.\n- You want revocation today → wait for v0.2 (VC Status List), or fork.\n\n---\n\n## How it compares\n\n| | `agent-id` | `@digitalbazaar/vc` | SpruceID `ssi` | Hand-rolled JWT | A2A Agent Cards |\n|---|---|---|---|---|---|\n| Agent-native profile | **yes** | no | no | no | partial |\n| Self-custody | **yes** | yes | yes | yes | no (TLS-anchored) |\n| Runtime deps | **5** | ~30 (jsonld+) | Rust | 1-2 | none (built-in) |\n| Spec + conformance | **yes** | partial | partial | no | partial |\n| Lines of source | **~400** | ~thousands | ~tens of thousands | trivial | n/a |\n| JSON-LD processing | **JCS, no RDFC** | RDFC | RDFC | n/a | none |\n| Revocation in v0.1 | no (v0.2) | yes | yes | n/a | n/a |\n\n**The design call:** `eddsa-jcs-2022` (JCS canonicalization) instead of `eddsa-rdfc-2022` (full RDF Dataset Canonicalization). JCS is RFC 8785 — deterministic JSON, ~50 LoC of dependency. RDFC needs the full `jsonld` library (runtime context fetching + a graph processor). For a profile this small with one signature suite, JCS is the right cut.\n\n---\n\n## Conformance\n\n```bash\nbun run conformance\n```\n\nThree vectors covering every (Cn) clause in [SPEC §6](./SPEC.md#6-conformance):\n\n| Vector | Clause | What it proves |\n|---|---|---|\n| [`c1-valid.json`](./conformance/c1-valid.json) | **C1** | Round-trip: a valid capability VC issues + verifies clean |\n| [`c2-mutated.json`](./conformance/c2-mutated.json) | **C2** | Tampering rejected: single-byte mutation in `capability.action` fails verification |\n| [`c3-didweb.json`](./conformance/c3-didweb.json) | **C3** | `did:web` chain: principal at `did:web:example.com` signs a VC for an agent at `did:web:example.com:agents:alice`, verifier resolves both DIDs and validates the signature |\n\nVectors are deterministic — same seed material, same Ed25519 signature byte-for-byte. Any implementation can run them and compare.\n\nTo re-generate (e.g. when adding new vectors):\n\n```bash\nbun run conformance/_generate-c1.ts \u003e conformance/c1-valid.json\nbun run conformance/_generate-c2.ts \u003e conformance/c2-mutated.json\nbun run conformance/_generate-c3.ts\n```\n\n---\n\n## Architecture\n\n- **Runtime:** [Bun](https://bun.sh) — TypeScript native, single binary, fast.\n- **Crypto:** [`@noble/ed25519`](https://github.com/paulmillr/noble-ed25519), [`@noble/hashes`](https://github.com/paulmillr/noble-hashes) — audited, zero-dep, pure JS.\n- **Canonicalization:** [`canonicalize`](https://github.com/erdtman/canonicalize) — RFC 8785 JCS.\n- **DID encoding:** [`multiformats`](https://github.com/multiformats/js-multiformats) — multibase + multicodec.\n- **Schema:** [`ajv`](https://github.com/ajv-validator/ajv) — JSON Schema 2020-12.\n- **Test runner:** `bun test` (built-in).\n\nFive runtime dependencies. Every file under 200 lines. No HTTP server, no JSON-LD processor, no ORM, no framework.\n\n```\nagent-id/\n├── src/                # 7 files, ~400 LOC\n│   ├── index.ts         # public API barrel\n│   ├── types.ts         # all shared TypeScript types\n│   ├── keys.ts          # Ed25519 + did:key codec\n│   ├── jcs.ts           # canonicalization + hash\n│   ├── vc.ts            # issue() + verify()\n│   ├── schema.ts        # ajv wrapper\n│   └── resolve.ts       # did:key (offline) + did:web (fetch)\n├── schema/             # JSON Schema deliverable\n├── context/            # JSON-LD context deliverable\n├── conformance/        # vectors + runner\n├── examples/           # demo\n├── tests/              # 56 tests, 9 files\n└── SPEC.md             # v1.0 normative spec\n```\n\n---\n\n## Roadmap\n\n### v0.2 (deferred from v0.1)\n\n- HTTP server endpoints (`/credentials/issue`, `/credentials/verify`, `/resolve/{did}`)\n- VC Status List 2021 revocation\n- `did:peer` support\n- Issuer override sugar (currently library-level only)\n\n### Non-goals (permanent)\n\n- A new DID method — reuse `did:key` and `did:web`.\n- A blockchain.\n- A wallet UI.\n- A generic VC framework — use `@digitalbazaar/vc` if that's what you need.\n- Tool / function descriptions — that's [MCP](https://modelcontextprotocol.io/)'s job.\n\n---\n\n## Family\n\n`agent-id` is the foundation in an 8-repo family of agent-native primitives. Each solves one problem absurdly well, composes mature primitives, and has its own SPEC + conformance suite.\n\n| Repo | What it does | Depends on `agent-id` for |\n|---|---|---|\n| `agent-phone` | sync RPC over a self-custody session | session handshake, peer identity |\n| `agent-toolprint` | signed tool-call receipts (DSSE-like) | author signatures |\n| `agent-cid` | content-addressed artifact manifests | producer signatures |\n| `agent-ask` | self-hostable Q\u0026A protocol for agents | signer identity |\n| `agent-pay` | Lightning + L402 invoices for agents | invoice signer |\n| `agent-scroll` | canonical byte-deterministic transcripts | (independent) |\n| `agent-rerun` | reproducibility bundles | (independent) |\n\n---\n\n## Status\n\n**v0.1.0 — shipped.** [SPEC.md](./SPEC.md) at v1.0. Reference library frozen. CI green on every push.\n\n[CHANGELOG](./CHANGELOG.md) tracks each release. [SCOPE.md](./SCOPE.md) records what was deliberately included or cut for this version, with reasoning.\n\n---\n\n## Contributing\n\nIssues and PRs welcome. Three things to know before opening one:\n\n1. **Conformance is the product.** Any change to `verify()`'s observable behavior must come with a conformance vector that pins the new behavior.\n2. **Five-dep budget.** Adding a runtime dep needs a one-paragraph justification in the PR description. The bar is high — see [SCOPE.md](./SCOPE.md) for what got cut.\n3. **No file over 200 lines** unless there's a structural reason.\n\nRun `bun test \u0026\u0026 bun run conformance \u0026\u0026 bun run lint \u0026\u0026 bun run typecheck` before pushing.\n\n---\n\n## License\n\nApache 2.0 — see [LICENSE](./LICENSE).\n\n---\n\n## Acknowledgements\n\n`agent-id` is a thin profile composing audited primitives. The hard work was already done by:\n\n- [W3C VC Working Group](https://www.w3.org/2017/vc/WG/) — VC Data Model + Data Integrity\n- [W3C DID Working Group](https://www.w3.org/2019/did-wg/) — DID Core\n- [Paul Miller](https://paulmillr.com) — `@noble/ed25519`, `@noble/hashes`\n- [Anders Rundgren](https://github.com/erdtman) — `canonicalize` (RFC 8785)\n- [Protocol Labs](https://github.com/multiformats) — `multiformats`\n- [Ajv contributors](https://github.com/ajv-validator/ajv) — JSON Schema validation\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fp-vbordei%2Fagent-id","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fp-vbordei%2Fagent-id","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fp-vbordei%2Fagent-id/lists"}