What is SignedApproval?

SignedApproval is a standalone cryptographic human-in-the-loop verification service. Any app or AI agent sends an approval request; the human authenticates with passkey, TOTP, or biometrics; the caller receives an Ed25519-signed proof that a real human approved the action.

Key Concepts

The Problem: AI agents and automation tools are increasingly performing high-stakes actions on behalf of humans — deploying code, transferring money, approving access. But how do you prove that a real human authorized a specific action? Slack messages can be spoofed. Email approvals can be intercepted. Button clicks leave no cryptographic trail.

The Solution: SignedApproval provides unforgeable, offline-verifiable proof that a real human approved a specific action at a specific time. Every approval decision is signed with Ed25519 — the same elliptic curve cryptography used in SSH keys, cryptocurrency, and TLS certificates.

How it differs from other approval tools:Services like HumanLayer use Slack-based approvals that rely on trust in a third-party chat platform. SignedApproval produces a cryptographic signature that anyone can verify independently, without trusting SignedApproval's servers. The proof is mathematical, not social.

How It Works

The approval flow has three participants: the caller (your app, agent, or CI pipeline), the approver (a human with a registered account), and the verifier (anyone who needs to confirm the approval happened).

  1. Caller creates a request — POST to /api/v1/approvals/request with the action description and TTL.
  2. Approver receives notification — Push notification on iOS, or visible in the web dashboard.
  3. Approver authenticates — Passkey (WebAuthn/FIDO2), TOTP, or Face ID verifies the human is who they claim.
  4. Approver decides — Approve or reject. The decision is signed with the approver's Ed25519 key.
  5. Caller receives the signed decision — Via webhook callback or polling. Includes the Ed25519 signature.
  6. Anyone can verify — The public verification endpoint returns the signature and public key. Offline verification is also possible.

The Signed Payload

Every approval decision produces a canonical JSON payload that is signed with Ed25519:

JSON
{
  "v": 1,
  "rid": "request-uuid",
  "did": "decision-uuid",
  "approver": "sha256(user_id)[:16]",
  "action": "sha256(action_text)[:16]",
  "decision": "approved",
  "method": "passkey",
  "ts": 1709000000,
  "exp": 1709086400,
  "nonce": "random-hex-32"
}

The signature covers all fields. Changing any value — even a single character — invalidates the signature. The approver and action fields are hashed for privacy: you can verify the approval without exposing who approved what.

Who Uses SignedApproval

SignedApproval serves as shared infrastructure for human verification across any application:

  • AI Agent Frameworks — LangChain, CrewAI, OpenAI Agents, and custom agent pipelines can gate high-risk tool calls behind signed human approval.
  • CI/CD Pipelines — Require a signed approval before deploying to production, merging to main, or running destructive migrations.
  • Financial Operations — Prove that a human authorized a transfer, invoice payment, or budget change.
  • Compliance & Audit — Maintain a cryptographically verifiable audit trail of human authorizations.
  • Git Platforms — GitHub, Bitbucket, and GitLab integrations gate PR merges with approval checks.

Authentication Methods

SignedApproval supports three authentication methods for proving the approver is who they claim:

  • Passkeys (WebAuthn/FIDO2) — Hardware-backed, phishing-resistant credentials. The gold standard.
  • TOTP Authenticator — Time-based one-time passwords from apps like Google Authenticator or Authy.
  • Biometric (Face ID) — Native iOS Face ID or Touch ID for frictionless mobile approvals.
Tip
SignedApproval accounts use Google OAuth for login — there are no email/password credentials to manage. This is a deliberate security decision: for a security product, the authentication baseline must be high.

Open API

SignedApproval exposes a simple REST API that any application can call. The API uses bearer token authentication with sa_live_ prefixed API keys. Verification is public and requires no authentication.

bash
# Create an approval request
curl -X POST https://signedapproval.net/api/v1/approvals/request \
  -H "Authorization: Bearer sa_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"action":"Deploy v2.1.0 to production","ttl_seconds":3600}'

# Verify a signed decision (public, no auth required)
curl https://signedapproval.net/api/v1/approvals/{id}/verify