Edge

Agent Tooling

Agent Self-Signup

Agents can create their own Edge account with no human in the loop, anchored to an Ed25519 keypair instead of an email address. A human claims the account later to unlock it.

How It Works

The whole flow is two unauthenticated API calls. The agent proves control of a cryptographic key, pays a small computational cost, and receives a working account plus a scoped access code (ea_live_...) in the response.

  1. POST /agent/signup/challenge — get a nonce and the current proof-of-work difficulty
  2. Solve the proof of work and sign the challenge with an Ed25519 private key
  3. POST /agent/signup — receive the account and access code
  4. Nominate a human operator by email (at signup or later) — they claim the account from the control panel to lift the guest restrictions

The flow is fully self-describing: an unauthenticated GET /agent/signup returns machine-readable instructions, so an agent pointed at edge.network/agent with no credentials discovers signup on its own from the 401 response.

The Guest Tier

A self-created account starts in a restricted guest tier: the agent can explore and plan, but cannot create real resources or spend anything until a human claims the account.

Allowed Blocked
Full API discovery, all read endpoints, dry-run planning with cost estimates (X-Dry-Run: true), nominating a human operator, checking claim status All real resource creation and mutation — deployments, VMs, buckets, DNS zones, widgets, spending of any kind

Unclaimed guest accounts are automatically deleted after about 7 days. Claiming the account preserves it and everything the agent has configured.

Complete Example

Node.js, no dependencies:

import crypto from 'node:crypto'

const BASE = 'https://edge.network'

// 1. Generate an Ed25519 keypair (or reuse one you already control)
const { publicKey, privateKey } = crypto.generateKeyPairSync('ed25519')
const publicKeyB64url = Buffer.from(
  publicKey.export({ format: 'jwk' }).x, 'base64url'
).toString('base64url')

// 2. Request a challenge
const challenge = await fetch(BASE + '/agent/signup/challenge', { method: 'POST' })
  .then(r => r.json())

// 3. Solve the proof of work: sha256(nonce + ":" + solution)
//    needs `difficulty_bits` leading zero bits
function solvePow(nonce, bits) {
  for (let i = 0; ; i++) {
    const hash = crypto.createHash('sha256').update(nonce + ':' + i).digest()
    let zeros = 0
    for (const byte of hash) {
      if (byte === 0) { zeros += 8; continue }
      zeros += Math.clz32(byte) - 24
      break
    }
    if (zeros >= bits) return String(i)
  }
}
const powSolution = solvePow(challenge.nonce, challenge.proof_of_work.difficulty_bits)

// 4. Sign the challenge to prove key control
const message = 'edge-agent-signup\n' + challenge.nonce + '\n' + publicKeyB64url
const signature = crypto.sign(null, Buffer.from(message), privateKey).toString('base64')

// 5. Sign up
const result = await fetch(BASE + '/agent/signup', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    challenge_id: challenge.challenge_id,
    public_key: publicKeyB64url,
    signature,
    pow_solution: powSolution,
    name: 'My Deploy Agent',
    email: 'operator@example.com',   // optional: triggers the claim email
  }),
}).then(r => r.json())

// Store this securely — it is shown exactly once
console.log(result.access_code.secret)   // ea_live_...

Verification Details

Proof of key control

Sign the UTF-8 string edge-agent-signup\n<nonce>\n<public_key> with your Ed25519 private key, where <public_key> is your raw 32-byte public key, base64url-encoded (the JWK x value). Send the 64-byte signature base64-encoded. This is the same Ed25519 primitive used by Web Bot Auth / HTTP Message Signatures, so agents with an existing verified-agent key can reuse it. One account per public key.

Proof of work

Find any string pow_solution (1–128 characters) such that sha256("<nonce>:<pow_solution>") has the required number of leading zero bits (returned by the challenge endpoint; typically 20, about a second of compute). The difficulty is tuned dynamically with abuse pressure. Challenges expire after 10 minutes and are single-use. Per-IP rate limits apply on top.

Human Claim Flow

To unlock the account, the agent nominates its human operator — either with the email field at signup, or later:

curl -X POST https://edge.network/agent/signup/bind-email \
  -H "Authorization: Bearer ea_live_..." \
  -H "Content-Type: application/json" \
  -d '{"email": "operator@example.com"}'

The operator receives an email with a claim link. They sign in to (or create) an Edge account with that same email address, review what the agent has set up, and claim it. Ownership transfers to them: the account appears in their account switcher, guest restrictions lift, and they control the agent's access codes, permissions, and budgets from Account → Agent Access — including instant revocation. Claim links expire after 7 days. The agent can poll GET /agent/signup/status to see when the claim lands.

Claiming is free and safe: the account stays on the free plan, and nothing can be charged unless the owner explicitly adds a card or prepaid balance afterwards.

See Also