Spark resource extension for explicit idempotency and one-time nonce protection.
A protected action must choose a strategy and a nonempty scope. Nonce protection has no stored-response or external-effect surface and always fails closed.
onetime
Protect effectful Ash actions with explicit keyed-effect semantics.
Nested DSLs
- protect
- response
onetime.protect
protect actionProtects one effectful action with explicit keyed-effect semantics.
Nested DSLs
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
action | atom | The name of the Ash action to protect (a create, update, destroy, or action). |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
strategy | atom | The keyed-effect strategy: :idempotency (replay-safe, stores a response) or :one_time_nonce (single-use, no stored response). Every protection must declare one. | |
scope | list(any) | The nonempty identity scope that partitions keyed effects. Components are static strings, tenant/attribute references, or resolver modules; missing scope is an error. | |
key | any | The key source that names a single keyed effect within the scope: a client idempotency argument, a verified proof, or a minted token. | |
fingerprint | keyword | Optional content fingerprint (arguments: / attributes: lists) that distinguishes distinct effects under the same key. | |
retention | any | How long a stored idempotent response is retained before it may be re-executed, as a {count, unit} tuple (e.g. {24, :hour}). | |
window | keyword | Nonce replay window bounds: max_age: and clock_skew: as {count, unit} tuples. Applies to :one_time_nonce strategies. | |
external_effect | module | Optional module exporting the external-effect contract for idempotent actions that must observe or reverse a side effect. Not available for nonce strategies. | |
on_definite_store_failure | :fail_closed | :execute_untracked | :fail_closed | What to do when the authoritative store is definitively unavailable: :fail_closed (reject) or :execute_untracked (run once with telemetry, no replay safety). |
limits | keyword | [] | The single, unified vocabulary of size bounds for this protection. Valid keys: max_key_bytes, max_token_bytes, max_scope_components, max_fingerprint_bytes, verifier_timeout_ms, and max_cache_entry_bytes bound the key/verification/cache paths; max_response_bytes, max_response_depth, max_response_nodes, max_response_entries, and max_response_scalar_bytes bound the response payload (structural limits). Each is a positive integer at or below its package ceiling. Unknown keys are rejected at compile time. Response bounds apply only to idempotent strategies (which store a payload); nonce strategies accept the keys but do not encode a response. |
onetime.protect.response
response codecDeclares the response codec, field allowlist, and result classifier.
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
codec | module | The module implementing the response codec. Must export format_tag/0, encode/3, and decode/4 and yield a tag the store accepts. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
fields | list(atom) | [] | The resource attributes projected into the stored/replayed response payload. Acts as the field allowlist; attributes not named here never enter the response. |
classify | module | The module exporting classify/2 that decides whether a result is stored, rejected, or rolled back. Required for idempotency strategies. | |
codec_opts | keyword | [] | Codec-specific options forwarded to the codec: the third argument to encode/3 and the fourth argument to decode/4. |
Introspection
Target: AshOnetime.Resource.Response
Introspection
Target: AshOnetime.Resource.Protection