agent-id.io

v1.0.2

OpenClaw skill for the agent-id.io identity and trust service. Use it to register an AI agent, authenticate with challenge/response, manage passkeys and cryp...

0· 69·0 current·0 all-time

Install

OpenClaw Prompt Flow

Install with OpenClaw

Best for remote or guided setup. Copy the exact prompt, then paste it into OpenClaw for plak/agent-id-io.

Previewing Install & Setup.
Prompt PreviewInstall & Setup
Install the skill "agent-id.io" (plak/agent-id-io) from ClawHub.
Skill page: https://clawhub.ai/plak/agent-id-io
Keep the work scoped to this skill only.
After install, inspect the skill metadata and help me finish setup.
Use only the metadata you can verify from ClawHub; do not invent missing requirements.
Ask before making any broader environment changes.

Command Line

CLI Commands

Use the direct CLI path if you want to install manually and keep every step visible.

OpenClaw CLI

Bare skill slug

openclaw skills install agent-id-io

ClawHub CLI

Package manager switcher

npx clawhub@latest install agent-id-io
Security Scan
Capability signals
CryptoRequires walletRequires OAuth tokenRequires sensitive credentials
These labels describe what authority the skill may exercise. They are separate from suspicious or malicious moderation verdicts.
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Benign
medium confidence
Purpose & Capability
The name/description (agent-id.io client for registration, auth, passkeys, key rotation, and verifications) match the included scripts and SKILL.md examples. All network calls target the agent-id.io API (or user-supplied proof URLs) and the cryptographic functionality (keygen, sign, rotate, derive) is expected for this purpose.
Instruction Scope
Runtime instructions tell the user/agent to run local scripts that generate private keys, write keyfiles, and save JWTs/tokens. That is within the declared purpose, but the skill explicitly performs sensitive local file I/O (writing agent_keys.json, new keys, PGP/SSH private keys, token files). The SKILL.md warns to keep keys secret, but consumers should still treat these scripts as privileged local tooling.
Install Mechanism
No install spec is provided (instruction-only), and dependencies are limited and pinned (cryptography, requests). That is proportionate; there is no ad-hoc remote download or archive extraction that would increase risk.
!
Credentials
The manifest lists no required env vars, but the code reads environment variables (AGENT_ID_API to override the API base, AGENT_ID_TOKEN used by rotate --apply, and AGENT_KEY_PASSPHRASE referenced by key encryption helpers). These env vars are reasonable for the tool, but the SKILL.md/registry metadata do not declare them — a visibility gap. Users should be aware tokens/passphrases supplied via env are used by scripts and are sensitive.
Persistence & Privilege
The skill is not always-enabled and does not request platform-wide privileges. It writes and replaces files under user control only (agent key files, backups). It does not modify other skills or system-wide agent settings.
Assessment
This skill appears to implement a legitimate client for agent-id.io, but it handles sensitive private keys and tokens locally — review and accept the risks before use. Before installing/using: - Inspect the scripts yourself (they are included) and ensure you trust the code and the hardcoded API defaults. - Be aware the code can read AGENT_ID_API (to point at a different server), AGENT_ID_TOKEN (used for applying rotations), and AGENT_KEY_PASSPHRASE (for encrypted keyfiles). These env vars are not declared in the registry metadata — do not set them to values you don't trust. - Prefer creating and encrypting keyfiles (use the --encrypt option) and avoid leaving plaintext agent_keys.json or private key files world-readable. - Consider running pip-audit on the pinned deps (cryptography, requests) and run the scripts in an isolated environment. - If you will derive SSH/PGP keys (derive_keys.py), note those will create private keys that could be reused elsewhere — treat them as sensitive secrets and store/back them up according to your policies. If you want higher assurance, ask the author for: an explicit list of env vars the skill uses, a signed release or canonical homepage/source repo, and confirmation of no telemetry or hidden endpoints. If any AGENT_ID_API value is set to a non-official URL, do not authenticate — that could leak your signatures to an attacker.

Like a lobster shell, security has layers — review code before you run it.

latestvk971src55edz2dwpwnxe8s4p6184zygj
69downloads
0stars
3versions
Updated 1w ago
v1.0.2
MIT-0

agent-id.io

What it is: OpenClaw skill for operating against the agent-id.io service. The service provides identity, authentication, verification, and trust primitives for AI agents. Each agent has a self-sovereign Ed25519/X25519 keypair, and authentication uses challenge/response plus passkey-based flows without sending private keys to the server.

Base URL: https://agent-id.io/v1

Setup (pinned dependencies)

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Dependency policy:

  • Runtime dependencies are pinned in requirements.txt
  • If you maintain this skill, run pip-audit and your preferred test flow before publishing updates

1. Register a New Agent

Generate keypair locally, then POST to register. The server never receives the private key.

# Generate Ed25519 signing key + X25519 encryption key
python3 scripts/keygen.py
# → Outputs: agent_keys.json (private, keep secret) + public keys as base64

# Register
curl -s -X POST https://agent-id.io/v1/agents/register \
  -H "Content-Type: application/json" \
  -d '{
    "display_name": "my-agent",
    "public_sign_key": "<base64 Ed25519 pubkey>",
    "public_enc_key":  "<base64 X25519 pubkey>"
  }'
# → { "agent_id": "uuid", "display_name": "...", "created_at": "..." }

Save the agent_id and agent_keys.json securely. Lost private key = lost identity.


2. Authenticate (Get a Token)

Authentication is a two-step challenge/response:

AGENT_ID="<your-uuid>"

# Step 1: Get challenge
CHALLENGE=$(curl -s -X POST https://agent-id.io/v1/auth/challenge \
  -H "Content-Type: application/json" \
  -d "{\"agent_id\": \"$AGENT_ID\"}" | python3 -c "import json,sys; print(json.load(sys.stdin)['challenge'])")

# Step 2: Sign challenge + verify
python3 scripts/sign_challenge.py "$CHALLENGE" agent_keys.json
# → Outputs the auth/verify payload as JSON

# POST the signed payload
TOKEN=$(curl -s -X POST https://agent-id.io/v1/auth/verify \
  -H "Content-Type: application/json" \
  -d "$(cat signed_challenge.json)" | python3 -c "import json,sys; print(json.load(sys.stdin)['token'])")

Token is a JWT, valid 15 minutes, not refreshable. Re-authenticate when expired.

Usage: Authorization: Bearer $TOKEN


3. Manage Passkeys

Passkeys = the WebAuthn credentials tied to your agent's public key. Free tier: 2 passkeys max.

Add a passkey

curl -s -X POST "https://agent-id.io/v1/agents/$AGENT_ID/passkeys" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "credential_id": "<base64url>",
    "public_key": "<base64url>",
    "attestation_object": "<base64url>"
  }'

List passkeys (via agent profile)

curl -s "https://agent-id.io/v1/agents/$AGENT_ID"

Delete a passkey

curl -s -X DELETE "https://agent-id.io/v1/agents/$AGENT_ID/passkeys/<passkey_id>" \
  -H "Authorization: Bearer $TOKEN"
# 204 No Content on success
# 409 last_passkey → cannot delete the only remaining passkey

4. Rotate Cryptographic Keys

Use when private key is compromised or as routine hygiene. Requires signing new key with old private key.

python3 scripts/rotate_keys.py agent_keys.json
# → Generates new_agent_keys.json + rotation_payload.json

curl -s -X POST "https://agent-id.io/v1/agents/$AGENT_ID/keys/rotate" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(cat rotation_payload.json)"
# → { "agent_id": "...", "public_sign_key": "<new>", "rotated_at": "..." }

After rotation: replace agent_keys.json with new_agent_keys.json. Old tokens are still valid until expiry.


5. Verify Identity

Three verification methods — all start a pending verification, then a check call resolves it.

Domain TXT verification

# Start verification
curl -s -X POST "https://agent-id.io/v1/agents/$AGENT_ID/verify/domain" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domain": "example.com"}'
# → { record_name: "_agent-id.example.com", expected_txt_value: "agent-id-verification=..." }

# Add DNS TXT record, then check
curl -s -X POST "https://agent-id.io/v1/agents/$AGENT_ID/verify/domain/check" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domain": "example.com"}'

Code repository

# Start: provide repo URL + proof file URL
curl -s -X POST "https://agent-id.io/v1/agents/$AGENT_ID/verify/code-repo" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"repo_url": "https://github.com/org/repo", "proof_url": "https://raw.githubusercontent.com/org/repo/main/.well-known/agent-id-proof.txt"}'
# → { expected_proof_value: "agent-id-verification=..." }

# Create .well-known/agent-id-proof.txt with exact value, commit, then check
curl -s -X POST "https://agent-id.io/v1/agents/$AGENT_ID/verify/code-repo/check" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"proof_url": "..."}'

Website file

# Start
curl -s -X POST "https://agent-id.io/v1/agents/$AGENT_ID/verify/website-file" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"domain": "example.org"}'
# → Proof file expected at https://example.org/.well-known/agent-id-verification.txt

# Create file with exact expected value, then check
curl -s -X POST "https://agent-id.io/v1/agents/$AGENT_ID/verify/website-file/check" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"domain": "example.org"}'

6. Sponsorship

Sponsorship = cryptographic vouching. Sponsor signs the sponsored agent's public key.

# Request sponsorship from a known agent
curl -s -X POST https://agent-id.io/v1/sponsorship/request \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"sponsor_agent_id": "<sponsor-uuid>"}'

# Sponsor: view pending requests
curl -s https://agent-id.io/v1/sponsorship/requests \
  -H "Authorization: Bearer $SPONSOR_TOKEN"

# Sponsor: approve (sign requester's public_sign_key with your private key)
python3 scripts/sign_sponsorship.py <requester_public_sign_key_base64> agent_keys.json
curl -s -X POST "https://agent-id.io/v1/sponsorship/requests/<request_id>/approve" \
  -H "Authorization: Bearer $SPONSOR_TOKEN" -H "Content-Type: application/json" \
  -d '{"sponsor_signature": "<base64 Ed25519 sig>"}'

7. Look Up Agents (Public, No Auth)

# Get agent profile
curl -s "https://agent-id.io/v1/agents/<agent_id>"

# Get agent's public keys
curl -s "https://agent-id.io/v1/agents/<agent_id>/keys"

# List agents sponsored by a specific agent
curl -s "https://agent-id.io/v1/agents?sponsor=<sponsor_agent_id>"

8. Derive SSH + PGP Keys from Master Seed

The Ed25519 master seed is the single source of truth. All other keys are derived deterministically — one backup covers everything.

# Derive SSH + PGP keys from agent_keys.json master seed
python3 scripts/derive_keys.py agent_keys.json --out-dir ~/.ssh

# Outputs:
#   ~/.ssh/id_agent_ed25519      (SSH private key, OpenSSH format, chmod 600)
#   ~/.ssh/id_agent_ed25519.pub  (SSH public key)
#   ~/.ssh/agent_pgp_private.asc (PGP private key, ASCII-armored)
#   ~/.ssh/agent_pgp_public.asc  (PGP public key)

# Import PGP key to GPG keyring
gpg --import ~/.ssh/agent_pgp_private.asc

Key hierarchy:

master_seed (Ed25519 seed, 32 bytes)
├── HKDF(info="agent-id/ssh-ed25519") → SSH Ed25519 key
└── HKDF(info="agent-id/pgp-ed25519") → PGP Ed25519 key

Keys are deterministic: the same agent_keys.json always produces the same SSH + PGP keys. Safe to regenerate anytime from backup.


9. Secure Key Storage

The agent is responsible for keeping the master keyfile secure. Treat agent_keys.json like a private key — it IS one.

Security warning: inline environment variable assignments like AGENT_KEY_PASSPHRASE=... python3 ... are less safe. They can be exposed through /proc/<pid>/environ, shell history, process logging, or terminal scrollback.

Encrypt the keyfile (AES-256-GCM + scrypt):

# Encrypt (preferred: interactive prompt, avoids exposing the passphrase inline)
python3 scripts/secure_keyfile.py encrypt agent_keys.json
# → creates agent_keys.json.enc
rm agent_keys.json  # delete plaintext

# Decrypt on use (preferred: interactive prompt)
python3 scripts/secure_keyfile.py decrypt agent_keys.json.enc --out /tmp/keys.json
python3 scripts/authenticate.py /tmp/keys.json --save-token /tmp/agent_token.jwt
rm /tmp/keys.json /tmp/agent_token.jwt  # delete immediately after use

# Less safe fallback: passphrase via environment variable
AGENT_KEY_PASSPHRASE="<strong-passphrase>" python3 scripts/secure_keyfile.py encrypt agent_keys.json
AGENT_KEY_PASSPHRASE="<strong-passphrase>" python3 scripts/secure_keyfile.py decrypt agent_keys.json.enc --out /tmp/keys.json

Where the passphrase lives:

  • A secret manager you already trust
  • An environment variable injected at runtime, for example AGENT_KEY_PASSPHRASE
  • Never hardcoded, never in config files, never in git

Storage pattern:

  • Keep agent_keys.json.enc as the portable encrypted artifact
  • Store the passphrase separately from the encrypted file
  • If you sync backups offsite, encrypt first and verify restore steps periodically

Backup strategy:

  • The encrypted agent_keys.json.enc can be stored anywhere you already trust for encrypted backups
  • The passphrase must be stored separately from the keyfile
  • Losing both = permanent identity loss

Scripts

All scripts are in scripts/. See each file's header for usage.

ScriptPurpose
scripts/register.pyFull registration incl. PoW challenge/solve
scripts/authenticate.pyAuth flow → JWT token (--save-token or --print-token)
scripts/keygen.pyGenerate Ed25519 + X25519 keypair → agent_keys.json
scripts/sign_challenge.pySign auth challenge manually → signed_challenge.json
scripts/rotate_keys.pyGenerate new keypair + rotation signature
scripts/sign_sponsorship.pySign requester's pubkey for sponsorship approval
scripts/derive_keys.pyDerive SSH + PGP keys from master seed (HKDF)
scripts/secure_keyfile.pyEncrypt/decrypt agent_keys.json (AES-256-GCM + scrypt)

Error Handling

Key errors to handle:

ErrorMeaningAction
409 conflictKey already registeredGenerate new keypair
409 passkey_limit_reachedFree tier: max 2 passkeysDelete old or upgrade
409 last_passkeyCannot delete last passkeyAdd another first
403 agent_revokedIdentity revokedCall POST /agents/{id}/unrevoke
400 invalid_challengeChallenge expired (>60s)Re-fetch challenge
401 unauthorizedToken expired or invalidRe-authenticate

For full API reference: references/api.md

Comments

Loading comments...