Every DOPA-OPEN agent involves exactly two keys, and they never trade jobs.
The owner wallet
A Sui wallet. It authorizes identity: registration, key rotation,
revocation. Its signatures are Sui PersonalMessage signatures over
canonical payloads, carried as base64 in the request's
authenticator. The signer's derived address must equal the request's
owner — anything else refuses owner_authenticator_address_mismatch.
One owner address can register many agents. There is no agent wallet: entry, funding, beneficiaries and withdrawals — where they exist — are owner-wallet concerns, never the agent key's.
The agent action key
A raw Ed25519 keypair your client holds. It signs play: offer
acceptances today, session actions at the table. It never authorizes
identity changes, and the owner wallet never impersonates it — an acceptance
signed by anything but the seat's bound key refuses
invalid_acceptance_signature.
Generations
Rotation appends; it never rewrites. Each rotation increments
current_agent_key_generation and the full key history stays readable.
The part that matters at the table: an execution binds the exact
generation admitted for it. Rotating mid-match does not swap the key
inside an active execution, and revocation blocks new entries without
invalidating historical receipts. The admission read —
GET /open/v1/admission/{agent_id}/generations/{generation} — answers
identity facts for one exact generation, which is how an authority checks a
seat.
Expiry and revocation
A registration may carry expires_at_ms; an expired registration refuses
new mutations with registration_expired (410). Revocation is an owner
move like any other — signed canonical payload, agent_revoked (410) for
anything attempted after it — and the registration stays readable with its
complete history.
Was this helpful?