Back to Nodes

Allowly

v0.5.1
Last updated Oct 12, 2026

n8n community node for sealing JSON records and checking agent actions with Allowly

25 Weekly Downloads
964 Monthly Downloads

Included Nodes

Allowly

Description

n8n-nodes-allowly

Community n8n node for Allowly.

Use it to seal and verify JSON records, or to authorize and check an AI agent, tool, or automation step. The default SEAL flow needs only the private webhook URL copied from the Allowly dashboard. Map JSON into the node and it returns portable signed evidence.

Install in n8n

Version 0.5.0 uses SDK 0.8.0 and verifier 5.0.0, with receipt wire 5 only. Durable Execute operations are self-hosted only; n8n Cloud verification and restart safety are not claimed.

On self-hosted n8n, an Owner or Admin can install the package:

1. Open n8n.
2. Go to Settings -> Community Nodes.
3. Install n8n-nodes-allowly. For local testing, build and pack this checkout instead:

npm run build
npm pack --ignore-scripts

The verified integration page is at
n8n.io/integrations/allowly. Queue-mode
deployments must install the package on every worker and webhook processor as
well as the main instance.

Import the SEAL starter workflow

Download the managed SEAL workflow JSON,
then use Import from File in n8n. The workflow is inactive and contains no
credential, private URL, workflow ID, or token.

Open SEAL in Allowly, copy the private webhook URL, and save it in one
Allowly SEAL Webhook API credential. Attach that credential to **2. SEAL +
WAIT + VERIFY**, map your JSON and optional receipt details, and execute the
workflow. Verified evidence is written to an n8n Data Table; a pending result
is kept out of the evidence table and carries the attempt ID needed for later
retrieval.

Example: Stripe refunds with review

The Stripe test-refund example targets
n8n-nodes-allowly 0.5.0. Import the workflow, configure credentials and a
stored authorization, then test allow, deny, confirmation, and escalation paths.
It binds approval to the refund request, checks again after review, and preserves
the Stripe result separately from the decision receipt.

Example: MCP agent crash test

The poisoned agent called your n8n MCP tool. Zoho Mail never got the call.

Import the guarded MCP tool and crash-test one risky action.
The package includes an inactive, credential-free workflow, synthetic inbox and
customer data, Allowly action/policy setup, and an example MCP client config.
Only a validated allow can reach Zoho Mail through its MCP server; every other decision, a malformed
response, or an Allowly error stops first.

The workflow uses the verified n8n-nodes-allowly.allowly type at node version
2. Read the guide before importing. It explains the exact credential and
authorization placeholders, the deterministic denied test, and what a signed
decision receipt does and does not prove.

Set up Allowly Identity for agent workflows

Version 0.5.0 supports native Allowly Identity, Auth0, and unbound
authorizations through the Identity selector.

For an enrolled Allowly agent, choose Allowly Identity in the Allowly API
credential. Set it up once before running protected actions:

1. Create the agent and its policy in Allowly. Keep the exact agent ID.
2. Install the Allowly CLI,
sign in, and enroll that agent:

   npm install -g @allowly-ai/cli
   allowly login
   allowly agent enroll  --out /secure/path/credential.json
   

3. In n8n, create an Allowly API credential. Enter the workspace’s runtime
API Key, set Identity to Allowly Identity, and paste the complete
JSON from the completed file into Allowly Identity Credential. Paste the
JSON itself, not a file path or an identity token.
4. After enrollment succeeds, use Create Authorization once for that agent’s
policy. Store the returned authorizationId for your workflow.
5. Run Check with that stored authorization and a policy action. This checks
the native identity and writes a decision receipt. Confirm the expected
decision before connecting a provider action.

Enrollment registers only the public key with Allowly. The private credential
stays in the owner-only CLI file, then in n8n’s encrypted credential store. Use
the completed version-1 file with provider: "allowly", workspace_id,
agentid, bindingid, keyid, and privatekey_jwk. Keep all API keys,
private credentials, and identity tokens out of workflow JSON, items, and logs.

The node signs a 60-second identity token locally using Ed25519 and sends it for
Check, Check & Enforce, and Acknowledge Receipt. The CLI is not needed
when the workflow runs. The runtime API key is still required. Enrollment uses
the CLI setup login; a runtime API key cannot enroll an agent.

The credential’s Test button only lists one authorization to test the API
key. It does not test the private credential or its authorization binding. Use
the Check test above to validate native identity.

Existing authorizations keep the identity recorded when they were created.
Enrollment does not bind an old authorization. When migrating, create a new or
replacement authorization after enrollment, then deliberately update the
workflow’s stored ID and test it. A native identity credential cannot be used
with an unbound authorization. Keep No External Identity for existing
unbound authorizations, or Auth0 Machine-to-Machine for an Auth0 binding.
The credential default remains No External Identity for compatibility.

Enrollment must be enabled on the target runtime, and its agent/key limits
apply. If enrollment is interrupted or returns
nativeagentenrollment_disabled, keep the pending file. Once enrollment can
complete, rerun the command with --resume and the same --out path before
creating the authorization.

Durable SDK Execute (self-hosted only)

The maintained node offers Execute HTTP, Continue HTTP Execution, Get Bound Execution Status, Reconcile HTTP Execution, and Verify Resolution Webhook. The SDK owns actual provider dispatch, request commitments, immutable review continuation and crash recovery. There is no provider-node bypass or separate scheduler.

Set ALLOWLYN8NSTATE_DIRECTORY once on the self-hosted worker to an existing private, worker-owned absolute directory (mode 0700), on a durable mount. It is not a workflow parameter. This integration is tested with one n8n worker and one local durable filesystem. Multi-process, queue-worker and cross-host journal sharing are not verified here; do not assume that a shared directory alone provides those guarantees. Keep n8n execution data and Data Tables durable and access-controlled too. Ephemeral or n8n Cloud journals do not offer restart-safe Execute. Lost or ambiguous journals require reconciliation, never a new operation ID or provider retry.

In the existing Allowly API credential, set Execution Workspace ID from trusted workspace configuration. Keep the native enrolled credential or Auth0 configuration unchanged. Native tokens refresh through the existing loader for each SDK request; an unavailable bound identity fails closed. For callback verification, also store the private Resolution Webhook Signing Secret. Configure the workspace callback once using a setup credential, to the fixed verifying workflow—not a per-Wait URL.

The Original Execution Request is one unchanged JSON object:

{
  "url": "https://api.github.com/repos/octocat/Hello-World/issues?per_page=1",
  "operationId": "stablecustomerbusiness_operation",
  "authorizationId": "authfromexact_edition",
  "enabledExecutableId": "exefromworkspace",
  "catalogOperationId": "github.issues.list",
  "action": "github.issues.list",
  "method": "GET",
  "headers": {"accept": "application/vnd.github+json"},
  "evidenceMode": "receipt",
  "policyInput": {"resource": "synthetic:github-read", "context": {}}
}

Optional fields are body, timeoutMs and policyInput estimatedCostMicros. Identity, journal paths and native witness paths cannot come from this object. The same original object is used for status and Continue after native Wait. A stable operation ID is not a newly generated n8n execution ID. Request headers/body are customer-held private execution data; keep credentials out of workflow exports.

Execute/Continue output the SDK state (waitingforreview, notallowed, responseobserved, or unknown) and its authorization, review/evidence/outcome fields. Provider response bytes are not emitted. Status outputs execution, authenticated and compared to the original HTTP commitment. Every wrapper outputs protectedActionAllowed: false: dispatch already belongs to the SDK, never a following provider node. Receipt-mode outcomes are customer-reported; they do not independently prove a network request or business completion.

After Continue validates the SDK’s saved original request, an exact executionreviewnotavailable conflict triggers a bound review-status read. A recorded rejection finishes the node with {state: "denied", decision: "deny", reason: "reviewrejected", authorization, review, resolution, protectedActionAllowed: false, notificationOnly: false}. The original authorization and source receipt stay unchanged; resolution contains the recorded time and source/resolution receipt IDs. No provider is called and no execution outcome or receipt is invented. The SDK journal and API execution remain waiting: this is a terminal node choice, not a new SDK execution state. A repeated Continue returns the same recorded denial. Generic conflicts, network errors, expired/revoked/unknown reviews and mismatched status still fail as errors, not human rejection.

Webhook verification requires a native Webhook node with Raw Body enabled and its binary data field plus original headers. The SDK checks the exact bytes, signature, timestamp, workspace, schema and 16 KiB bound. Output is {event, notificationOnly: true, protectedActionAllowed: false}. Persist event IDs and match workspace/prompt/source receipt to the saved operation before an authenticated native wake. Notifications are not permission; read bound status and use SDK Continue.

The sibling demo repo contains two inactive, credential-free templates: workflows/allowly-native-execute-wait.json and workflows/allowly-native-resolution-callback.json. They use native Data Tables and a 90-second bounded authenticated Wait, then authoritative status fallback. A callback that arrives before the map or Wait is ready may be lost; the saved timeout path still checks status. The private resume URL is generated by n8n and never accepted from callback input.

The tested n8n 2.33.3 native URL has exactly /webhook-waiting/?signature=<64 lowercase hex>, at the configured trusted origin. The templates preserve this platform token, require the same Header Auth credential for native wakes, and reject any other path/query/origin. Keep these complete URLs private inside access-controlled n8n execution data and Data Tables.

Witnessed execution uses the unchanged native SDK/TLSNotary path and installed workspace witness configuration. The evidence directory is derived inside the fixed private root. Missing native witness setup fails before provider dispatch; receipt mode is not a witness substitute. Crash safety is at-most-one dispatch plus reconciliation, not guaranteed exactly-once completion.

All API-key operations, receipt polling, key reads and credential testing use the same operator endpoint. Production defaults to https://api.allowly.ai. A self-hosted operator may set ALLOWLYN8NAPIBASEURL to an HTTPS origin (no path, query or credentials). HTTP requires ALLOWLYN8NALLOWLOCALAPI=true and a loopback host or host.docker.internal; it is not a workflow or credential parameter. Keep the local switch off for hosted use. Authenticated calls never follow redirects. The SDK’s provider HTTPS/public-DNS checks are unchanged; the local integration lab makes only a fixed unauthenticated public GitHub GET (a remote read), not a customer action.

Operations

Seal JSON with Managed Webhook

1. Open SEAL in the Allowly dashboard and copy the private webhook URL.
2. In n8n, create an Allowly SEAL Webhook API credential and paste that URL into Private Webhook URL.
3. Choose Seal JSON with Managed Webhook and map the JSON record.
4. Run the node and save its receipt, key document, workspace ID, and original record.

No ordinary API key, policy, authorization, or local hashing step is required. The node sends the complete JSON record to the private webhook as the raw request body. Allowly hashes it in memory and does not retain the original record. The node keeps the mapped value in its output as record, or preserves exact input text as recordJson in Raw JSON Text mode.

Choose Parsed Value for ordinary n8n objects. Choose Raw JSON Text when exact number spelling, duplicate keys, and other byte-level details matter. Allowly applies the versioned allowly.seal.jcs-sha256.v1 profile and rejects malformed or unsafe JSON.

Optionally map Type, Reference, and Statement as Receipt details. For example, use invoice, INV-1042, and Approved for payment. The node sends them in the explicit Allowly-Seal-Type, Allowly-Seal-Reference, and Allowly-Seal-Statement headers, so the raw JSON body and its fingerprint stay unchanged. Each value accepts up to 256 printable ASCII characters with no leading or trailing whitespace; interior spaces are kept. Allowly stores the submitted details in the signed receipt; it does not extract them from the JSON or prove that the statement is true. Do not put secrets or the original record in these fields.

Wait for Signature is bounded from 0 to 300 seconds and defaults to 120. A 200 or 202 webhook response confirms only the current delivery state. The node reports sealed: true after it retrieves the signed receipt and keys and verifies both the signature and original record. If signing is still running when the wait ends, it returns pending: true with an attemptId.

The output metadata field carries the returned Receipt details and is null for older receipts with none. Once sealed, the node checks that metadata matches the signed receipt before returning verified evidence. A rejected attempt still fails with a safe error.

Set Idempotency Key to a stable sender event ID when the upstream system has one. A retry with the same key, exact JSON, and same Receipt details recovers the same attempt. Reusing the key after changing the JSON or a detail returns a conflict. If the field is blank, the node derives a stable key from the n8n execution, node, and item.

The private URL is an encrypted n8n credential. The node never adds it or any token-bearing status, receipt, or keys URL to workflow output or customer-facing errors. Credential testing performs a scoped GET; it never creates a seal.

Retrieve Managed Webhook Seal

Use Retrieve Managed Webhook Seal after a pending result. Map its attemptId and the same original recordJson or record, then use the same private webhook credential. The node waits for the selected bounded period, retrieves the receipt and keys through trusted credential-derived routes, and verifies the evidence. It returns another pending result if signing still has not finished.

Verify Saved JSON Seal

Use Verify Saved JSON Seal with the original JSON, signed receipt, saved key document, and expected workspace ID. This operation makes no network request and needs no API key or active webhook. It uses the same bundled Allowly verifier as the other SEAL operations and fails the workflow if the signature, record, or workspace does not match.

Keep the original JSON, full receipt, workspace ID, key document, and trusted key fingerprints together. Hosted receipt and key availability is not permanent.

Seal JSON Record (API Key)

The earlier direct API operation remains available for existing workflows. It hashes the record inside n8n, sends the fingerprint and optional short metadata to POST /v1/seal with an Allowly runtime API key, waits for signing, and verifies the receipt before returning success. It does not send the original JSON to Allowly.

Verify JSON Seal (API Key)

The earlier API-key verification operation also remains available. Supply the original JSON, full signed receipt, and expected workspace ID. The node retrieves workspace keys from the fixed Allowly API origin, then verifies the signature and record locally.

Create Authorization

Creates an authorization from a user and an agent policy:

POST /v1/authorizations
Authorization: Bearer allowlyl1s001_...
{
  "userid": "user123",
  "policyid": "salescopilotemailv1",
  "policy_version": 1,
  "actions": ["email.send"]
}

The node output includes authorizationId. Store it in your workflow or app data, then use it with the Check operation. The selected policy must define defaultexpirydays; this node does not invent an authorization expiry.

For Allowly Identity, enroll the agent before creating this authorization.
Creating it records the agent identity that must sign its checks. Enrollment
never changes an existing grant.

Copy the logical policy ID and exact positive integer edition from its published policy_ref into Policy ID and Policy Version. The node never selects a latest version. Action Scope (JSON) may contain a unique array of action names; leave it blank for all actions in the retained edition. Inline constraints, decision flags, duplicate names, and non-integer versions are rejected. The returned policyRef is the raw reference, including its retained definition hash. The node checks that the edition and any requested action scope match the API response.

Docs: Authorizations and agent policies.

Check

Checks one stored authorization before an action runs:

POST /v1/check
Authorization: Bearer allowlyl1s001_...
{
  "authorizationid": "auth...",
  "actions": ["email.send"],
  "resource": "gmail:thread:abc123",
  "client_timestamp": "2026-09-24T20:01:02.123Z",
  "context": {
    "workflowuserid": "user_123",
    "workflowagentid": "sales-copilot"
  }
}

Allowly authorizes from authorization_id. The user, agent, allowed actions, expiry, confirmation rules, escalation rules, and budget cap were defined when the authorization was created. Optional workflow user/agent fields in this node are copied into context only; they do not replace the authorization.

For confirm, map confirmNonce into Resolve Confirmation. For escalate, map escalationId into Resolve Escalation. After approval or resolution, run a second Check node with a different node name so it receives a fresh idempotency key; replaying the first key returns the first decision.

Docs: Check API and decisions and attributes.

Check & Enforce

Uses the same inputs as Check, but releases an item only when the selected
result is exactly allow. deny, confirm, escalate, a missing or malformed
result, and request failure stop the node. Confirmation and escalation must use
their existing resolution actions and a fresh check; they are never treated as
allow.

n8n still lets workflow owners create other routes. Do not connect a node-level
error output or Continue On Fail path to the protected action. This operation
also throws on non-allow when Continue On Fail is set, but workflow
configuration remains customer-controlled.

Run a provider action

Place Check & Enforce immediately before a provider node in the same
workflow. Only an exact allow releases the item. n8n runs the provider node
with its own credential; Allowly receives the policy fields and decision record,
not the provider credential or request. Keep provider credentials in n8n’s
encrypted credential store. This flow has a decision receipt, but no independent
witness of the provider response.

Acknowledge Receipt

Map the complete signed receipt into Signed Receipt after it is available.
The node computes the canonical SHA-256 locally, then records the hash and the
required customer-reported Client Timestamp through the acknowledgment API.
The resulting evidence records an authenticated workflow report. It is not a
customer signature.

Settle Budget

Reports the actual cost of a budgeted check. Map Check Receipt ID from the selected action’s normalized receiptId; for a multi-action check, use the budgeted action’s receipt ID. Run settlement in the same workflow while the check receipt still exists.

Resolve Confirmation

Approve or reject the confirm_nonce returned by Check. Approval is a customer-reported event and does not identify a named approver.

Resolve Escalation

Report an approved or rejected escalation using its escalation_id. Resolved By is an opaque, customer-reported identifier recorded in the escalation receipt.

Fields

Credential fields

  • Allowly SEAL Webhook API / Private Webhook URL: the complete private URL copied from the dashboard. This is the only credential needed for managed sealing and retrieval. Treat it like a password.
  • Allowly API / API Key: Allowly runtime key used by the older direct SEAL operations and authorization operations.
  • Allowly API / User ID Pepper: optional encrypted value used only by Mask Email Locally. Back it up; changing it changes derived user IDs.
  • Allowly API / Identity: choose Allowly Identity for an authorization bound to native identity, Auth0 Machine-to-Machine for an Auth0 binding, or No External Identity for an unbound authorization. The existing default remains No External Identity.
  • Allowly Identity Credential: required when Identity is Allowly Identity. Paste the complete, successfully enrolled CLI credential JSON. Its private key stays in n8n credential storage; the node returns neither the credential nor its signed tokens in items or errors.
  • Auth0 Issuer, Auth0 Audience, Auth0 Client ID, and Auth0 Client Secret: customer Auth0 machine credential stored by n8n. The node validates the exact HTTPS issuer, obtains a short-lived token without following redirects, and reuses it only while unexpired during the current node execution. Secrets and tokens are not returned in items or errors.
  • Production webhook credentials must use the hosted Allowly API at https://api.allowly.ai. For local development only, enable Allow Local Development URL on the credential to accept a private URL on localhost, 127.0.0.1, or ::1. When n8n SSRF protection is enabled, keep N8NSSRFPROTECTIONENABLED=true and add only the loopback hostname in use, such as N8NSSRFALLOWEDHOSTNAMES=localhost. These advanced settings are not part of customer credential setup.

    Managed SEAL fields

  • JSON Input: parsed n8n value or original raw JSON text.
  • JSON Record / Raw JSON Text: the complete record. Seal JSON with Managed Webhook sends it to Allowly for in-memory hashing. Retrieval and verification compare it locally without sending it again. The webhook enforces a 1 MiB UTF-8 limit and maximum nesting depth of 32.
  • Type, Reference, and Statement: optional Receipt details, each up to 256 printable ASCII characters with no leading or trailing whitespace. Interior spaces are kept. They are stored with the signed receipt. Reference supports exact retained-receipt search and is not an idempotency key.
  • Idempotency Key: optional stable sender event ID. Reusing it with the same JSON and details recovers the original attempt; changing either conflicts.
  • Wait for Signature: maximum time to poll, from 0 to 300 seconds. A timeout returns a pending result rather than claiming the record is sealed.
  • Attempt ID: opaque ID from a pending result, used by Retrieve Managed Webhook Seal.
  • Signed Seal Receipt, Saved Key Document, and Expected Workspace ID: retained evidence used by Verify Saved JSON Seal without a credential or network request.
  • API-key SEAL fields

  • JSON Record / Raw JSON Text: record hashed locally, with a 1 MiB UTF-8 limit and maximum nesting depth of 32.
  • Request ID: stable retry ID. Reusing it with the same fingerprint and profile returns the original logical seal; changing the content conflicts. A new ID creates a new seal.
  • Metadata: optional object of up to eight short string values copied into the signed context. Do not put secrets or raw records in metadata.
  • Signed Seal Receipt: full signed wire-5 receipt or Allowly receipt envelope to verify.
  • Expected Workspace ID: caller-trusted workspace retained from the authenticated sealing flow.
  • Create Authorization fields

  • Policy ID: reusable agent policy ID copied from the Allowly dashboard. The policy defines the agent and the actions the user is authorizing.
  • User Identifier: choose how this node produces user_id.
  • User ID: opaque internal app user ID sent directly as user_id.
  • User Email: email to mask locally when User Identifier is set to Mask Email Locally.
  • Check fields

  • Authorization: stored Allowly authorization ID returned by Create Authorization.
  • Action(s): one action name or comma/newline-separated action names to check.
  • Resource: optional action target, for example gmail:thread:abc123.
  • Session: optional workflow/session label copied into the signed receipt.
  • Estimated Cost Micros: optional micro-USD estimate for budgeted authorizations, from 0 through 9007199254740991. 50000000 means $50.00. Reserved amounts stay charged until a Settle Budget step reports the actual cost.
  • Workflow User: optional n8n workflow context field for traceability.
  • Workflow Agent: optional n8n workflow context field for traceability.
  • Additional Context JSON: optional JSON object copied into the Allowly check context and receipt.
  • Client Timestamp: optional timezone-aware, customer-reported event time. It never replaces Allowly’s receipt time.
  • Settle Budget fields

  • Check Receipt ID: normalized receiptId from the budgeted action in the Check output.
  • Actual Cost (micro-USD): actual integer cost from 0 through 9007199254740991. The check must include an estimate.
  • Idempotency Key: optional replay key; defaults to the n8n execution ID plus the check receipt ID.
  • Why not use an email as user_id?

    Allowly receipts are durable proof artifacts. If you send a raw email as user_id, that email can become part of API requests, logs, traces, and signed receipt payloads. That may be exactly what you want in a few internal systems, but it is usually not the privacy-safe default.

    Prefer one of these:

  • An opaque internal ID, such as user_123.
  • A locally masked email ID, such as email_hmac:v1:....

The Mask Email Locally mode does the masking inside n8n before the API request:

1. Trim whitespace.
2. Lowercase the email.
3. HMAC-SHA256 with your User ID Pepper.
4. Send only email_hmac:v1: to Allowly.

The raw email is not sent to Allowly and is not included in the node output. The pepper stays in the encrypted Allowly credential. Do not lose or rotate it casually: if it changes, the same email derives to a different user_id, and existing authorizations will no longer match.

More: PII-safe identifiers.

Output

Managed SEAL output

{
  "attemptId": "swd_...",
  "workspaceId": "ws_...",
  "status": "sealed",
  "sealed": true,
  "pending": false,
  "signatureVerified": true,
  "recordMatches": true,
  "profile": "allowly.seal.jcs-sha256.v1",
  "recordSha256": "...",
  "receiptId": "rcp_...",
  "recordedAt": "2026-09-12T14:32:00.000Z",
  "receipt": {},
  "keysDocument": {},
  "trustedKeyFingerprints": [],
  "record": {}
}

Raw JSON mode returns recordJson instead of record so the original text can be archived.

If signing is still running, sealed is false, pending is true, and the signed evidence fields are null. Map attemptId and the original record into Retrieve Managed Webhook Seal. No output contains the private webhook URL or a token-bearing URL.

API-key Seal output

The older Seal JSON Record (API Key) operation returns the same portable evidence fields with its direct requestId instead of a webhook attemptId.

Verify SEAL output

{
  "verified": true,
  "signatureVerified": true,
  "recordMatches": true,
  "failureReason": null,
  "expectedWorkspaceId": "ws_...",
  "receipt": {},
  "keysDocument": {},
  "trustedKeyFingerprints": []
}

Create Authorization output

{
  "authorizationId": "auth_...",
  "userId": "email_hmac:v1:...",
  "policyId": "salescopilotemail_v1",
  "policyVersion": 1,
  "policyRef": {
    "policyid": "salescopilotemailv1",
    "policy_version": 1,
    "definition_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
  },
  "actions": ["email.send"],
  "receipt": {
    "status": "pending",
    "receiptid": "rcp..."
  },
  "response": {}
}

Check output

The node outputs the most restrictive action’s convenient fields plus the full response. The order is deny, escalate, confirm, then allow, so a multi-action check cannot hide a denied action behind an earlier allowed one.

receiptId works with pending and signed envelopes. receiptUrl uses the operator’s validated API endpoint, not a URL supplied by the server. Both are null when no receipt is returned. authorizationId is the original requested authorization. A signed payload must match that authorization, selected action, decision and reason. The original receipt envelope is unchanged. Decoding a signed receipt does not verify its signature. workspaceId comes only from Execution Workspace ID in the credential; it is null when not configured. A configured workspace must match a signed receipt’s payload.

The refund and MCP crash-test examples require that trusted workspace field. Their Code nodes use the packaged decoder at n8n-nodes-allowly/dist/nodes/Allowly/seal-verifier.js. Install the same local package on the Code execution runtime (including a separate task runner, if used) and allow the package with NODEFUNCTIONALLOWEXTERNAL=n8n-nodes-allowly. Keep other required allowlist entries, but do not use *. Missing decoder access stops the workflow before a protected action. These examples retain original JWS segments and report receiptVerification: "notperformed"; use the maintained verifier with independently trusted workspace/key settings for proof verification.

{
  "action": "email.send",
  "authorizationId": "authfromrequest",
  "decision": "allow",
  "reason": "authorizationgrantedaction_active",
  "receiptId": "rcp_...",
  "receiptUrl": "https://api.allowly.ai/v1/receipts/rcp_...",
  "workspaceId": "wsfromcredential",
  "receipt": {
    "status": "pending",
    "receiptid": "rcp..."
  },
  "results": {
    "email.send": {
      "decision": "allow",
      "reason": "authorizationgrantedaction_active"
    }
  },
  "response": {
    "authorizationid": "auth...",
    "results": {}
  }
}

Receipt wire 5

This package bundles the published verifier 5.0.0 and accepts wire 5 only.
After npm ci, run npm run refresh:verifier to rebuild from the registry-locked
package and record its public tarball, integrity and source commit.
SEAL checks signatures and record hashes; it does not replay policy or verify
transactional enforcement.