FIRST-PARTY CUSTOMER-SIDE JOURNAL · POSTGRESQL

Replace the journal placeholder with one durable PostgreSQL contract.

The official adapter gives every Gate worker atomic begin, primary reads and compare-and-set over one customer-controlled PostgreSQL namespace. MandateShield never receives the database credentials.

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.sql

These 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, get and compareAndSet to the same writable primary.
  • Keep synchronous_commit at on, remote_write or remote_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.