Identity anchor
Domain, not display name
The canonical issuer identity is the domain. Claimed names in the issuer profile are secondary metadata.
Issuer Setup
Host a cryptographic identity on your domain, verify it once, then issue signed credentials through the CLI or via your AI tools using the MCP server.
From zero to a publicly verifiable signed badge.
Run the onboarding command to generate an Ed25519 keypair and a starter issuer profile JSON. Keep your private key secret — the public key goes in the well-known file in the next step.
badge-cli onboard-issuer --domain yourdomain.com --name "Your Org Name"
This outputs three files:
issuer-private.pem, issuer-public.pem, and
openbadges-issuer.json.
Upload openbadges-issuer.json to your web server so it
is reachable at the path below. HTTPS is required. Serve with
Content-Type: application/json.
https://yourdomain.com/.well-known/openbadges-issuer.json
{
"@context": "https://www.w3.org/ns/credentials/v2",
"id": "https://yourdomain.com/.well-known/openbadges-issuer.json",
"type": ["Profile"],
"name": "Your Org Name",
"url": "https://yourdomain.com",
"publicKey": [
{
"id": "https://yourdomain.com/.well-known/openbadges-issuer.json#key-1",
"type": "Ed25519VerificationKey2020",
"controller": "https://yourdomain.com/.well-known/openbadges-issuer.json",
"publicKeyMultibase": "z..."
}
]
}
Submit your domain to the public trust API. This fetches your well-known file, validates its structure, checks key discoverability, and writes a domain trust record. Rate-limited — no API key required.
curl -X POST "https://badges.firmament.works/public/api/issuers/verify" \
-H "Content-Type: application/json" \
-d '{"domain":"yourdomain.com"}'
{
"trustState": "DOMAIN_VERIFIED_SIGNATURE",
"issuerDomain": "yourdomain.com",
"message": "Domain verified successfully."
}
Use the CLI to create a credential subject, sign it with your private key, and output a portable JSON badge file. The signed file can be hosted anywhere and verified by anyone using the public API.
badge-cli sign-badge \ --issuer-key issuer-private.pem \ --badge-class "Research Comprehension" \ --recipient-email [email protected] \ --recipient-name "Alex Smith" \ --summary "Completed synthesis of three conflicting papers."
Add the Signet MCP server to Claude Desktop, Cursor, or any MCP-compatible client. Your AI tool can then create badge classes, issue credentials, and sign them using the same API contract — with your API key set in the environment.
{
"mcpServers": {
"signet": {
"command": "npx",
"args": ["-y", "signet-mcp"],
"env": {
"SIGNET_API_KEY": "<your-api-key>",
"SIGNET_BASE_URL": "https://badges.firmament.works"
}
}
}
}
Once connected, prompt your AI: "Issue a badge for Alex Smith for completing the onboarding module." The MCP server handles key lookup, signing, and returns a verify URL you can share immediately. See llms.txt for machine-readable API docs.
Host your signed badge JSON at any HTTPS URL and share a verify link. Anyone — no account, no platform — can check the trust state using the public verifier or directly via the API.
https://badges.firmament.works/verify.html?url=https%3A%2F%2Fyourdomain.com%2Fbadges%2Fbadge.json&autoverify=1
curl "https://badges.firmament.works/public/api/verify/badge/https%3A%2F%2Fyourdomain.com%2Fbadges%2Fbadge.json"
Trust scope is explicit. No authority claims are made beyond what the cryptography proves.
Identity anchor
The canonical issuer identity is the domain. Claimed names in the issuer profile are secondary metadata.
Scope
Verification proves the badge was signed by a key discoverable on the issuer's domain at verification time — not assessment quality or accreditation status.
Portability
Signed badges are portable JSON files. They can be hosted anywhere, shared as URLs, and verified by anyone without platform access.
Not ready to set up an issuer yet? Create a signed demo badge on example.com and verify it immediately.