<!--
This file was generated by Spark. Do not edit it by hand.
-->
# AshOnetime.Resource

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](#onetime-protect)
   * response





### onetime.protect
```elixir
protect action
```


Protects one effectful action with explicit keyed-effect semantics.

### Nested DSLs
 * [response](#onetime-protect-response)




### Arguments

| Name | Type | Default | Docs |
|------|------|---------|------|
| [`action`](#onetime-protect-action){: #onetime-protect-action .spark-required} | `atom` |  | The name of the Ash action to protect (a create, update, destroy, or action). |
### Options

| Name | Type | Default | Docs |
|------|------|---------|------|
| [`strategy`](#onetime-protect-strategy){: #onetime-protect-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`](#onetime-protect-scope){: #onetime-protect-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`](#onetime-protect-key){: #onetime-protect-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`](#onetime-protect-fingerprint){: #onetime-protect-fingerprint } | `keyword` |  | Optional content fingerprint (`arguments:` / `attributes:` lists) that distinguishes distinct effects under the same key. |
| [`retention`](#onetime-protect-retention){: #onetime-protect-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`](#onetime-protect-window){: #onetime-protect-window } | `keyword` |  | Nonce replay window bounds: `max_age:` and `clock_skew:` as `{count, unit}` tuples. Applies to `:one_time_nonce` strategies. |
| [`commit`](#onetime-protect-commit){: #onetime-protect-commit } | `:with_action \| :independent` | `:with_action` | Nonce commit boundary. `:with_action` (default) commits the nonce claim inside the protected action's transaction, so an action-body failure rolls the spend back (correct for a single-use authenticator whose retry bears a fresh proof). `:independent` commits the claim in its own transaction before the action body runs, so a body failure leaves the proof spent for the acceptance window — RFC 9449 §11.1 request-attempt scope (the DPoP replay fence). Applies to `:one_time_nonce` only; rejected for `:idempotency`. |
| [`external_effect`](#onetime-protect-external_effect){: #onetime-protect-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`](#onetime-protect-on_definite_store_failure){: #onetime-protect-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`](#onetime-protect-limits){: #onetime-protect-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
```elixir
response codec
```


Declares the response codec, field allowlist, and result classifier.





### Arguments

| Name | Type | Default | Docs |
|------|------|---------|------|
| [`codec`](#onetime-protect-response-codec){: #onetime-protect-response-codec .spark-required} | `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`](#onetime-protect-response-fields){: #onetime-protect-response-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`](#onetime-protect-response-classify){: #onetime-protect-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`](#onetime-protect-response-codec_opts){: #onetime-protect-response-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`





<style type="text/css">.spark-required::after { content: "*"; color: red !important; }</style>
