Skip to main content

Overview

The Open Agent Trust Registry is a community-maintained registry of organizations authorized to issue credentials for AI agents. It provides a decentralized answer to the question: “Can I trust that this agent is who it claims to be?” The registry operates on three principles:
  1. Open participation — any organization can submit a registration PR
  2. Threshold governance — changes require multi-signature approval from existing issuers
  3. Protocol integration — registered issuers anchor into SINT Protocol capability tokens

Community Fork

github.com/pshkv/open-agent-trust-registry — active development

Upstream Org

github.com/sint-ai — canonical source, SINT Protocol integration

How It Works

1

Issuer submits a registration

An organization generates an Ed25519 keypair and submits a JSON registration entry to the data/ directory via pull request. The entry contains their public key, a canonical issuer ID, and metadata.
2

Existing issuers co-sign

The PR requires threshold signatures from a quorum of already-registered issuers. This prevents unilateral additions and ensures existing participants vouch for new entrants.
3

Entry is merged

Once threshold is met, the PR is merged. The issuer’s public key is now trusted by all consumers of the registry.
4

Agents present credentials

When an agent connects to a system, it presents a credential signed by its issuer. The verifying party checks the issuer’s public key against the registry.
5

SINT gateway enforces trust

The SINT Protocol gateway server resolves issuer trust at intercept time. Tokens from untrusted issuers are denied. The /.well-known/agent-trust.json endpoint serves the current registry state.

Registered Issuers

8 issuers are currently registered in the trust registry.
#Issuer IDStatus
1agent-passport-systemActive
2agentidActive
3agentinternetruntimeActive
4agoraActive
5arcedeActive
6arkforgeActive
7insumerapiActive
8qntmActive
Query the live registry from a running gateway:
curl http://localhost:4100/.well-known/agent-trust.json
Response:
{
  "version": "1.0",
  "updatedAt": "2024-01-01T00:00:00.000Z",
  "issuers": [
    {
      "id": "agent-passport-system",
      "publicKey": "ed25519:base64url_encoded_public_key",
      "endpoint": "https://agentpassport.example.com",
      "registeredAt": "2024-01-01T00:00:00.000Z",
      "metadata": {
        "name": "Agent Passport System",
        "url": "https://agentpassport.example.com",
        "contact": "[email protected]"
      }
    }
    // ... 7 more
  ],
  "threshold": {
    "required": 3,
    "total": 8
  },
  "rootSignature": "ed25519:base64url_root_sig"
}

Registry Structure

open-agent-trust-registry/
├── data/
│   ├── issuers/
│   │   ├── agent-passport-system.json
│   │   ├── agentid.json
│   │   ├── agentinternetruntime.json
│   │   ├── agora.json
│   │   ├── arcede.json
│   │   ├── arkforge.json
│   │   ├── insumerapi.json
│   │   └── qntm.json
│   └── registry.json          # Aggregated registry with threshold signatures
├── schemas/
│   └── issuer.schema.json     # JSON Schema for issuer entries
├── scripts/
│   ├── register.ts            # Submit a new issuer registration
│   ├── verify.ts              # Verify a registration or credential
│   └── list.ts                # List all registered issuers
└── .well-known/
    └── agent-trust.json       # Served by gateway at /.well-known/agent-trust.json

Issuer Entry Format

Each issuer is stored as a JSON file in data/issuers/:
{
  "$schema": "../schemas/issuer.schema.json",
  "id": "arkforge",
  "publicKey": "ed25519:base64url_encoded_public_key",
  "endpoint": "https://credentials.arkforge.io",
  "registeredAt": "2024-01-01T00:00:00.000Z",
  "metadata": {
    "name": "Arkforge",
    "url": "https://arkforge.io",
    "contact": "[email protected]",
    "description": "AI agent identity and credential issuance for enterprise workflows"
  },
  "signatures": [
    {
      "issuerId": "agentid",
      "signature": "ed25519:base64url_signature",
      "signedAt": "2024-01-01T00:00:00.000Z"
    },
    {
      "issuerId": "agora",
      "signature": "ed25519:base64url_signature",
      "signedAt": "2024-01-01T00:00:00.000Z"
    },
    {
      "issuerId": "qntm",
      "signature": "ed25519:base64url_signature",
      "signedAt": "2024-01-01T00:00:00.000Z"
    }
  ]
}

CLI Tools

The registry ships CLI scripts for issuer management.
# List all issuers
npx ts-node scripts/list.ts

# Output:
# ID                      ENDPOINT                              REGISTERED
# agent-passport-system   https://agentpassport.example.com    2024-01-01
# agentid                 https://agentid.example.com          2024-01-02
# ...

# JSON output
npx ts-node scripts/list.ts --format json

Governance: Ed25519 Threshold Signatures

The registry uses Ed25519 threshold signatures to prevent any single party from adding or removing issuers unilaterally.

How Threshold Works

The registry enforces a required / total threshold defined in registry.json. With 8 registered issuers and a threshold of 3:
  • Any new registration PR needs signatures from at least 3 existing registered issuers
  • Any removal or modification of an existing entry needs the same quorum
  • The threshold itself can only be changed by a quorum of existing issuers
Existing issuers sign new registration requests using their Ed25519 private key:
import { sign } from '@noble/ed25519';
import { readFileSync } from 'fs';

const privateKeyHex = process.env.ISSUER_PRIVATE_KEY!;
const draft = JSON.parse(readFileSync('./data/issuers/new-org.json', 'utf8'));

// Sign the canonical form of the entry (sorted keys, no signatures field)
const { signatures, ...payload } = draft;
const message = JSON.stringify(payload, Object.keys(payload).sort());
const messageBytes = new TextEncoder().encode(message);
const privateKeyBytes = Buffer.from(privateKeyHex, 'hex');

const signature = await sign(messageBytes, privateKeyBytes);
const signatureBase64 = Buffer.from(signature).toString('base64url');

console.log(`ed25519:${signatureBase64}`);
// Paste this into the PR as a co-signer
Any party can independently verify that a registry entry has valid threshold signatures:
import { verify } from '@noble/ed25519';
import registry from './data/registry.json';

async function verifyIssuerEntry(issuerId: string): Promise<boolean> {
  const entry = registry.issuers.find(i => i.id === issuerId);
  if (!entry) return false;

  const { signatures, ...payload } = entry;
  const message = JSON.stringify(payload, Object.keys(payload).sort());
  const messageBytes = new TextEncoder().encode(message);

  let validSigs = 0;
  for (const sig of entry.signatures) {
    const cosigner = registry.issuers.find(i => i.id === sig.issuerId);
    if (!cosigner) continue;

    const pubKeyBytes = Buffer.from(
      cosigner.publicKey.replace('ed25519:', ''),
      'base64url'
    );
    const sigBytes = Buffer.from(
      sig.signature.replace('ed25519:', ''),
      'base64url'
    );

    const valid = await verify(sigBytes, messageBytes, pubKeyBytes);
    if (valid) validSigs++;
  }

  return validSigs >= registry.threshold.required;
}

SINT Protocol Integration

The trust registry integrates with SINT Protocol at two points:

1. Capability Token Issuance

When creating a capability token, you can bind it to a trust registry issuer. This means the token is only valid if the issuer is still in the registry at intercept time.
curl -X POST http://localhost:4100/v1/tokens \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "agent:my-assistant:v1",
    "resource": "payments:invoices",
    "action": "read",
    "issuerBinding": {
      "issuerId": "agentid",
      "agentCredential": "base64url_agent_credential_signed_by_issuer"
    },
    "tier": "standard",
    "expiresIn": 3600
  }'
The gateway verifies agentCredential against the issuer’s public key in the registry before issuing the token.

2. Discovery Endpoint

The gateway serves the current registry state at a standard well-known path:
curl http://localhost:4100/.well-known/agent-trust.json
The gateway caches the registry and refreshes it on a configurable interval. Set the refresh interval in your environment:
SINT_TRUST_REGISTRY_URL=https://raw.githubusercontent.com/sint-ai/open-agent-trust-registry/main/data/registry.json
SINT_TRUST_REGISTRY_TTL=3600  # seconds between refreshes
If the gateway cannot reach the registry URL at startup, it falls back to the last cached version. If no cache exists, tokens with issuerBinding will be denied. Ensure the registry URL is reachable from your deployment environment.

Registering as an Issuer

1

Generate an Ed25519 keypair

npx ts-node scripts/register.ts keygen --output ./my-keypair.json
Store the private key in a secrets manager. Never commit it to git.
2

Create your issuer entry

npx ts-node scripts/register.ts draft \
  --id your-org-id \
  --public-key ./my-keypair.json \
  --endpoint https://credentials.your-org.com \
  --name "Your Organization" \
  --contact [email protected] \
  --output data/issuers/your-org-id.json
The id field must be lowercase, alphanumeric, hyphens allowed, globally unique in the registry.
3

Open a pull request

Fork github.com/pshkv/open-agent-trust-registry, add your entry to data/issuers/, and open a PR. Include:
  • Your organization description
  • Use case for agent credential issuance
  • Contact information for the trust team
4

Collect threshold signatures

Reach out to existing registered issuers (contact info in each issuer’s metadata) to co-sign your registration. You need signatures from at least threshold.required issuers.Co-signers add their signature to the signatures array in your entry file and push to your PR branch.
5

Merge and deploy

Once the threshold is met, a registry maintainer merges the PR. Your issuer entry is now live. Update your deployment to reference the new registry URL.
The governance process is intentionally manual. This is by design — automated additions would undermine the trust model. Plan for 3–7 business days for co-signer coordination.

Security Considerations

If your Ed25519 private key is compromised, file an emergency PR to update your public key. This PR must still meet the signature threshold — contact registry maintainers directly at [email protected] for expedited review.After rotation, all credentials signed with the old key become invalid. Re-issue credentials to your agents using the new key.
An issuer can be removed from the registry via the same threshold governance process. Removal requires a quorum of co-signers to prevent a single bad actor from removing legitimate issuers.After removal:
  • The issuer’s public key is moved to data/revoked/
  • The gateway serves the updated registry within one TTL cycle
  • All tokens with issuerBinding referencing the revoked issuer start returning ISSUER_REVOKED at intercept time
The registry is stored in a GitHub repository. Its security model depends on GitHub’s access controls. Additional mitigations:
  • The registry.json root signature is verified independently of the repository contents
  • Pin a specific git commit hash in SINT_TRUST_REGISTRY_URL to prevent unauthorized updates from affecting your deployment
  • Consider hosting a mirror on infrastructure you control
# Pin to a specific commit
SINT_TRUST_REGISTRY_URL=https://raw.githubusercontent.com/sint-ai/open-agent-trust-registry/abc123def456/data/registry.json