Observed since 20 Oct, 18:29 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
1id
Hardware-anchored identity SDK for AI agents -- 1id.com
Hardware-anchored identity SDK for AI agents — 1id.com
An identity registrar for AI agents. Like a birth certificate registry, but for software.
npm install 1id
Requires Node.js 18 or later. Zero runtime dependencies.
import oneid from "1id";
// Enroll at declared tier (no TPM required, always works)
const identity = await oneid.enroll({ request_tier: "declared" });
console.log(`Enrolled as ${identity.handle}`);
// Call an API that accepts 1ID tokens. Tokens are sender-constrained (cnf.jwk):
// each request is signed with your enrolled key (RFC 9421), so a copied token
// alone is refused. This signs for you:
const token = await oneid.getToken();
const response = await oneid.fetch_with_airs_proof_of_possession(
token, "https://1id.com/api/v1/identity/devices");
// From the shell: oneid request GET https://1id.com/api/v1/identity/devices
// Check current identity
const me = oneid.whoami();
console.log(`I am ${me.handle} (tier: ${me.trust_tier})`);
RFC: draft-drake-email-hardware-attestation-03 Section 3, draft-drake-agent-identity-registry-04 Section 3.
| Tier | Hardware | Sybil Resistant | Trust Level |
|---|---|---|---|
sovereign | TPM (Intel, AMD, Infineon) with valid cert | Yes | Highest |
portable | YubiKey with PIV attestation (other PIV vendors are not yet accepted) | Yes | High |
virtual | VMware / Hyper-V / QEMU vTPM | No | Verified Hardware |
declared | None (software keys) | No | Software |
CRITICAL: request_tier is a REQUIREMENT, not a preference. You get exactly what you ask for, or an exception. No silent fallbacks.
oneid.enroll(options)Enroll this agent with 1id.com.
const identity = await oneid.enroll({
request_tier: "declared", // REQUIRED: trust tier
key_algorithm: "ecdsa-p256", // Optional: ecdsa-p256 (default; signs email), rsa-2048, ed25519 (auth only)
requested_handle: "my-agent", // Optional: vanity handle (without @)
operator_email: "human@example.com" // Optional: human contact
});
oneid.getToken()Get a valid OAuth2 access token (cached, auto-refreshes).
const token = await oneid.getToken();
// Sender-constrained: send it with oneid.fetch_with_airs_proof_of_possession(token, url, init)
oneid.whoami()Read the local identity (no network call).
const me = oneid.whoami();
// me.canonical_id, me.handle, me.trust_tier, me.agent_identity_urn, etc.
oneid.credentials_exist()Check if the agent has enrolled.
if (!oneid.credentials_exist()) {
await oneid.enroll({ request_tier: "declared" });
}
import * as crypto from "node:crypto";
import { signChallenge, verifyPeerIdentity } from "1id";
const nonce = crypto.randomBytes(32); // verifier: a fresh challenge
const bundle = await signChallenge(nonce); // prover: enrolled key + Registrar binding
const peer = await verifyPeerIdentity(nonce, bundle); // verifier
console.log(peer.agent_identity_urn, peer.trust_tier, peer.hardware_locked);
The verifier resolves the peer's identity at the AIRS Registry (it must be
operational), takes the current issuer from there, checks the Registrar binding
against that issuer's published keys, then checks the nonce signature with the
bound key. Trust tier and identity facts never come from the bundle. Online by
design (a decommissioned identity fails); the Python SDK (verify_peer_identity)
is equivalent and bundles are interchangeable.
All errors extend OneIDError:
import { OneIDError, NoHSMError, EnrollmentError, NetworkError } from "1id";
try {
await oneid.enroll({ request_tier: "sovereign" });
} catch (e) {
if (e instanceof NoHSMError) {
console.log("No TPM found — try 'declared' tier");
} else if (e instanceof NetworkError) {
console.log("Server unreachable — check connection");
}
}
The SDK uses a two-tier architecture:
cryptooneid-enroll) — handles all TPM/HSM hardware operations. Auto-downloaded from GitHub releases when neededFor declared tier enrollment, only the TypeScript SDK is needed. For sovereign (TPM) tier, the Go binary is automatically fetched.
Credentials are stored at:
%APPDATA%\oneid\credentials.json~/.config/oneid/credentials.jsonPermissions are set to owner-only (0600 on Unix).
The Python equivalent is available as oneid on PyPI:
pip install oneid
Both SDKs share the same API design and credential format.
Apache 2.0 — see LICENSE.
pip install oneidDownload counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
typescriptEnvironment{
"local_name": "typescript",
"alias": false,
"peer_metadata": null
} | ^5.4 | development |
@types/nodeEnvironment{
"local_name": "@types/node",
"alias": false,
"peer_metadata": null
} | ^25.3.0 | development |
Source distribution
{
"shasum": "cd18e011f39a6c3012224b8c4547c1ea665ef721",
"tarball": "https://registry.npmjs.org/1id/-/1id-0.5.0.tgz",
"fileCount": 47,
"integrity": "sha512-p7al8395WglEK0RkW3oBqRyIgDCAOG3CzLFsY11AwX/uZrXyB+qRO/+kLdxKKnOXiQNcXFWebTdWs2rirGTGQw==",
"signatures": [
{
"sig": "MEYCIQDHaTIIj8xyGxeZ3OuZAHWNMT3OUJ6weY8CYEJAY4ttEgIhAJ/W6qMr8tJ+AQdLOpwIBawgv0WTeG5kaNT7A6CeSWWb",
"keyid": "SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"
}
],
"unpackedSize": 220468
}Observed since 20 Oct, 18:29 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:7fbb042acac3b033b3dfd4b8a8433bdc23fdd7f2a8373c5d9564cfc8dae92d6c