Action expiration
Problem
World ID actions don't have a maximum validity period. OPRF keys for an action have to be retained indefinitely, and nullifiers for any past action can always be (theoretically) regenerated.
The Protocol should support and enforce a maximum validity period for every action.
Why this matters
- Privacy. Once an action expires, the OPRF keys backing it can be permanently destroyed. Nullifiers for that action can never be generated again, even under OPRF node collusion or a compromised authenticator. This is a structural privacy property we don't have today.
- Cost and hygiene. Permanently destroying expired keys reduces storage and operational surface area for OPRF nodes.
- Economics. Fees can scale with the validity period, giving RPs a direct incentive to pick retention windows that match their use case instead of defaulting to forever.
Alternatives in consideration
A few directions that have come up. Each has tradeoffs and open questions.
1. Encode the expiration into the action. The action ID becomes a hash of a struct that includes the expiration (and optionally other metadata like description, icon, message schema). Roughly:
struct ActionMeta { string description; string imgUrl; string messageSchema; }
struct ActionRequest { ActionMeta metaHash; uint64 expiresAt; bytes additionalData; }
// action ID = hash(ActionRequest)
Tradeoff: clean and self-contained, no extra infra. Risk is that RPs don't realize changing the expiration changes the action scope (and therefore the nullifier set).
2. Action registry. Actions are registered (e.g. on-chain) with their metadata and expiration. The Protocol enforces expiration against the registry.
Tradeoff: clearer semantics and easier to evolve. Adds a registration step and on-chain footprint per action.
3. Epoch-based OPRF keys. OPRF keys are bound to time epochs (e.g. 30, 90, 365 days). RPs pick an epoch when first using an action. Expiration is enforced cryptographically by destroying the key at the end of its epoch.
Tradeoff: enforcement is built into the key lifecycle, with strong cryptographic guarantees. Granularity is limited to a fixed set of bucket
Action expiration
Problem
World ID actions don't have a maximum validity period. OPRF keys for an action have to be retained indefinitely, and nullifiers for any past action can always be (theoretically) regenerated.
The Protocol should support and enforce a maximum validity period for every action.
Why this matters
Alternatives in consideration
A few directions that have come up. Each has tradeoffs and open questions.
1. Encode the expiration into the action. The action ID becomes a hash of a struct that includes the expiration (and optionally other metadata like description, icon, message schema). Roughly:
Tradeoff: clean and self-contained, no extra infra. Risk is that RPs don't realize changing the expiration changes the action scope (and therefore the nullifier set).
2. Action registry. Actions are registered (e.g. on-chain) with their metadata and expiration. The Protocol enforces expiration against the registry.
Tradeoff: clearer semantics and easier to evolve. Adds a registration step and on-chain footprint per action.
3. Epoch-based OPRF keys. OPRF keys are bound to time epochs (e.g. 30, 90, 365 days). RPs pick an epoch when first using an action. Expiration is enforced cryptographically by destroying the key at the end of its epoch.
Tradeoff: enforcement is built into the key lifecycle, with strong cryptographic guarantees. Granularity is limited to a fixed set of bucket