WHAT IT SOLVES
One owner across workers, restarts and regions
The Gateway v2 runtime requires a DurableGatewayJournal before it may consume a reservation or approach a provider. This first-party module implements the required begin, get and compareAndSet operations over a fixed versioned PostgreSQL table. A unique key elects one creator; a version, state and immutable-identity predicate elects one transition winner.
The module accepts a structural database.query(text, values) interface, compatible with a customer-configured node-postgres Pool or Client. It has no PostgreSQL driver dependency and performs no automatic migration, retry, deletion, logging or provider connection.
DOWNLOAD
Vendor the module, declarations and explicit SQL migration
curl --proto '=https' --tlsv1.2 -fsSLo mandateshield-postgres-gateway-journal.mjs https://mandateshield.com/sdk/v1.12.0/mandateshield-postgres-gateway-journal.mjs
curl --proto '=https' --tlsv1.2 -fsSLo mandateshield-postgres-gateway-journal.d.ts https://mandateshield.com/sdk/v1.12.0/mandateshield-postgres-gateway-journal.d.ts
curl --proto '=https' --tlsv1.2 -fsSLo postgres-gateway-journal-v1.sql https://mandateshield.com/sdk/v1.12.0/mandateshield-postgres-gateway-journal.sqlThese files are pinned to product release v1.12.0. Verify their published SHA-256 checksums before production deployment.
MIGRATE
Separate schema ownership from the runtime role
# Apply once with a database-owner migration role.
psql "$GATE_DATABASE_URL" --set ON_ERROR_STOP=1 --file postgres-gateway-journal-v1.sql
# Grant the Gate runtime role only schema USAGE, SELECT, INSERT and:
# UPDATE (version, state, record, updated_at)
# Do not grant DELETE, TRUNCATE, ALTER or schema ownership.The migration creates mandateshield_gate.gateway_journal_v1, rejects malformed keys, states, versions and oversized records, and revokes public access. Apply it deliberately in the customer database; the JavaScript module never changes schema.
INTEGRATE
Pass the checked journal into the existing Gateway
import { Pool } from "pg"
import {
createPostgresGatewayJournal
} from "./mandateshield-postgres-gateway-journal.mjs"
import {
createMandateShieldGateway
} from "./mandateshield-gateway.mjs"
const pool = new Pool({
connectionString: process.env.GATE_DATABASE_URL,
max: 20
})
const journal = createPostgresGatewayJournal({
database: pool,
namespace: "checkout.production"
})
// Required startup check. This does not attest topology or failover.
await journal.checkReadiness()
const gateway = createMandateShieldGateway({
journal,
mandateShield: processorClient,
provider: providerAdapter
})The namespace prevents accidental record collisions between deployments; it is not an authorization boundary. Use separate database roles or databases where tenant or environment isolation requires it.
DEPLOYMENT INVARIANT
Every executor must reach the same writable primary
- Use PostgreSQL 14 or newer with
READ COMMITTED. - Route every
begin,getandcompareAndSetto the same writable primary. - Keep
synchronous_commitaton,remote_writeorremote_apply. - Do not route reads to replicas or deploy independent regional writers. Split-brain journals are unsafe.
- Configure TLS, backup, replication, failover fencing and credential rotation in the customer's database platform.
checkReadiness() rejects a recovery server, read-only session, unsafe synchronous-commit setting, incompatible schema or missing constraints. It cannot prove that every Gate instance uses this endpoint, or that the customer's routing, replication and failover topology is globally linearizable. Its topology_attested result is always false.
DATA BOUNDARY
The journal and its credentials stay customer-controlled
The adapter runs inside the customer's Gate. The PostgreSQL connection string, database credential and journal rows are not sent to MandateShield. Do not place card data, bank credentials, wallet private keys, provider secrets or signed payment credentials in a Gateway journal record.
This module implements the generic Gateway coordination journal. It is separate from the x402 adapter's encrypted signed-payload artifactJournal. An x402 Gate still needs that distinct payment-credential store and its stronger confidentiality controls; supplying this PostgreSQL journal does not replace it.
ASSURANCE BOUNDARY
Reference implementation, not managed storage or certification
The fixed SQL and adapter reduce custom journal code and fail closed on malformed or identity-mismatched rows. They do not operate the customer's database, certify its topology, guarantee provider execution, establish non-bypassability or constitute an independent security audit.