Skip to content

db: add a table of data-plane session attach tokens - #808

Closed
NancyKwongPerplexity wants to merge 1 commit into
mainfrom
session-tokens-table
Closed

NancyKwongPerplexity wants to merge 1 commit into
mainfrom
session-tokens-table

Conversation

@NancyKwongPerplexity

@NancyKwongPerplexity NancyKwongPerplexity commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Adds the data_plane_session_tokens table so a data-plane session can hold more than one attach token. Today a session stores one token in data_plane_sessions.token_hash. Replaying the session's create with the same idempotency key overwrites that hash, so every token returned earlier stops working at once. Ten concurrent same-key replays leave nine callers holding tokens that fail with a non-retryable 401, and renewing a port session by replay can 401 requests still in flight on the previous token. The stacked change, #809, keeps every minted token valid until its own expiry. This PR adds only the storage, because the repository's migration-isolation check keeps migrations in their own PR.

  • Table data_plane_session_tokens(token_hash text PRIMARY KEY, session_id text NOT NULL REFERENCES data_plane_sessions ON DELETE CASCADE, expires_at timestamptz NOT NULL, created_at timestamptz NOT NULL DEFAULT now()), with an index on (session_id, expires_at) for per-session pruning and the cascade.
  • space_ro is fenced from the new token_hash column through RO_COLUMN_DENYLIST, as it is from data_plane_sessions.token_hash. space_user gets DML through default privileges.
  • The down migration drops the table.

Nothing reads or writes the table until #809 merges.

Validation

  • scripts/check-migration-versions.sh, scripts/check-postgres-migrations-isolated.sh and scripts/check-postgres-migrations-squawk.sh pass (Squawk: 0 issues).
  • cargo nextest run --all-features -p pplx-space-db-migrate passes as part of the full run listed in api: keep earlier attach tokens valid when a session create is replayed #809. That run includes fresh_database_bootstraps_migrates_as_migrator_and_fences, which requires every *token_hash column to be fenced from space_ro. With the denylist entry removed, it fails with data_plane_session_tokens.token_hash holds auth material but is not fenced from space_ro. It passes with the entry in place.
  • On a local Kind cluster (docs/installation.md), redeploying from the stacked branch ran the space-db-migrate Job, which recorded version 20261021182104 and created the table. The E2E results are in api: keep earlier attach tokens valid when a session create is replayed #809.

I did not run the down migration against a populated database.

Severity and risk

Severity: does not apply on its own. This PR is the storage for the fix in #809, which is moderate: replayed or renewed session tokens are rejected with a non-retryable 401.

Risk: low. The migration is additive: one new empty table and an index, no backfill, and no change to existing columns. It takes no lock on data_plane_sessions beyond the foreign-key reference. Roll back with the down migration, together with #809 if that has shipped, since #809 writes the table.

Rollout

Deploy this migration before #809. Releases without #809 ignore the table.

Stack

  1. This PR (base main).
  2. api: keep earlier attach tokens valid when a session create is replayed #809, the API and validation change, based on this branch. Merge this one first.

AI assistance: Claude Code drafted the code, tests, and this description; the author reviewed them.

A data-plane session stores one attach token in
data_plane_sessions.token_hash, so replaying the session's create with the
same idempotency key overwrites it and the token every earlier response
returned stops working at once.

Add data_plane_session_tokens, one row per token keyed by its hash, with its
own expires_at and removed with its session. An index on
(session_id, expires_at) serves per-session pruning and the cascade. The
existing columns are unchanged. space_ro is fenced from the new token_hash
column like data_plane_sessions.token_hash. Nothing reads or writes the
table yet; the API starts using it in a following change.
@NancyKwongPerplexity

Copy link
Copy Markdown
Collaborator Author

closing together with #809: the token table was only needed for that proposal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant