Security & Troubleshooting

The endpoint creates and deletes data, so it’s protected by three independent layers and two separate secrets. This page also collects every error code and the fixes for the problems you’re most likely to hit.

The two secrets

Two secrets with different jobs. They must be different values - the SDK throws SAME_SECRETS at startup if they match.

SecretEnv variableWho knows itPurpose
Shared secretAUTONOMA_SHARED_SECRETYou + AutonomaHMAC-signs every request. Autonoma signs; your SDK verifies.
Signing secretAUTONOMA_SIGNING_SECRETOnly youSigns the teardown token during up, verifies it during down. Autonoma stores it opaquely and can’t read it.
Terminal window
openssl rand -hex 32 # AUTONOMA_SHARED_SECRET
openssl rand -hex 32 # AUTONOMA_SIGNING_SECRET (must differ)

The three layers

Three layers protect the endpoint: a production guard, request signing, and a signed teardown token

Layer 1 - Production guard. The endpoint returns 404 whenever the app runs in production, unless you set allowProduction: true. Even if someone finds the URL, it stays dark in production. Each SDK reads its ecosystem’s standard production signal - NODE_ENV=production for Node, DJANGO_SETTINGS_MODULE / DEBUG=False for Django, MIX_ENV=prod for Elixir, APP_ENV/RAILS_ENV for PHP and Rails, and so on.

Layer 2 - Request signing (HMAC-SHA256). Every request carries an x-signature header: the HMAC-SHA256 of the raw body, keyed with the shared secret. The SDK verifies it automatically and rejects unsigned or tampered requests with 401.

Layer 3 - Signed refs token. When up creates data, the SDK signs the created record IDs into a refsToken using the signing secret. On down, it verifies that token before deleting anything - so down can only ever delete what up actually created. Autonoma just stores the opaque string and passes it back; it cannot forge or modify it.

AttackWhy it fails
Fake refs with made-up IDsNo valid token → rejected
A real token with altered refsRefs don’t match the token → rejected
A replayed token from last weekToken expired (24h) → rejected

What the SDK can and cannot do

  • up can only create. It invokes the factories you registered, which call your own services. It cannot update, delete, drop, truncate, or run raw SQL outside your factory bodies.
  • down can only delete what up created, verified by the signed token. It calls each factory’s teardown in reverse order.
  • The SDK never runs SQL itself. It calls your factories; they use whatever client your app already has.

Error codes

Every code the endpoint can return, with its fix:

CodeHTTPMeaningFix
INVALID_SIGNATURE401HMAC signature missing or doesn’t matchMake AUTONOMA_SHARED_SECRET match the value Autonoma uses for your app
INVALID_BODY400Body isn’t valid JSON, or a required field is missingMatch each record to its own top-level model key and supply every required field
UNKNOWN_ACTION400action isn’t discover, up, or downCheck the request is one of the three actions
INVALID_REFS_TOKEN403Refs token missing, malformed, or failed verificationUse the same AUTONOMA_SIGNING_SECRET between up and down
PRODUCTION_BLOCKED404Endpoint disabled in production modeSet allowProduction: true, or ensure the app isn’t in production mode
SAME_SECRETS500sharedSecret and signingSecret are identicalUse two different openssl rand -hex 32 values
FACTORY_MISSING_PK500A factory’s create didn’t return an idReturn at least { id: "..." } from every create
INTERNAL_ERROR500Unexpected server errorCheck your factory bodies and server logs

Other common problems

These aren’t error codes - they surface as database or validation failures:

ProblemCauseFix
FK violation on upA required foreign key is missingSet every FK (including the scope field) explicitly as a { "_ref": "alias" }
Invalid input for "<Model>"Missing required field, or records under the wrong model keyMatch each record to its own top-level model key and supply every required field
references unknown alias(es)A _ref points at an alias no record declaresDeclare the alias with _alias in the same payload, or fix the typo
FK violation on downCircular FK between tablesThe SDK handles cycles with deferred updates; if it still fails, check for untracked FKs
Parallel tests collideSame email/slug across runsPut testRunId in every unique field
Link copied