Production Considerations
Scope actions and replay protection to authenticated actors, tenants, and shared storage.
After reading this guide, you will know:
- Where the host must enforce authentication and tenant scope.
- Why the default idempotency store is not sufficient for multiple workers.
- Which delivery and provider guarantees the gem does not provide.
Scope every action to host identity
The engine inherits the host application’s controller and authentication filters. Configure an actor resolver when the host does not expose current_user. Resolve a submitted surface through a tenant-scoped query, and use an authorizer that checks the specific operation on that record.
config.actor_resolver = ->(controller) { controller.current_user }
config.surface_resolver = ->(surface_id, actor:, **) {
actor&.surfaces&.find_by(id: surface_id)
}
config.authorize_action = ->(invocation) {
OrderPolicy.new(invocation.actor, invocation.surface).refresh?
}
A nil surface resolution denies the action. If you do not use a resolver, your authorizer must own surface access and revision checks. Do not trust a client-provided actor or tenant identifier.
Use shared atomic replay storage
The default idempotency store is process-local memory. It cannot coordinate separate workers and is lost on restart. For a multi-process app, implement the claim and record contract on shared atomic storage and configure it:
config.idempotency_store = MyAtomicIdempotencyStore.new
config.idempotency_ttl = 900
A store must atomically distinguish a new claim, an in-progress claim, and a completed replay. A handler failure leaves its claim pending until expiry because side effects may already have happened. A handler that outlives its TTL can overlap a later claim. Enforce business-level uniqueness or transactions for irreversible operations. Idempotency reduces duplicate execution within its scope; it is not an exactly-once guarantee.
Plan for delivery and recovery
Action Cable and Turbo Streams do not guarantee ordered or durable delivery. Persist canonical response state in the host and serve an authorized snapshot when the browser emits openui:snapshot-required. Keep provider credentials on the server and avoid logging unredacted requests or response context.
confirmed: true is an application-level acknowledgement, not proof of human consent. For high-impact operations, require a signed approval or another server-verified control in the authorizer.
Next Steps
- Server Actions - register and authorize each callable operation.
- Streaming Responses - implement host-owned snapshot recovery.
- Configuration - review all defaults.