Skip to content

fix(api): validate bank ids on import and reserve the _ prefix - #5673

Merged
nicoloboschi merged 2 commits into
mainfrom
fix/bank-id-validation-import
Oct 16, 2026
Merged

nicoloboschi merged 2 commits into
mainfrom
fix/bank-id-validation-import

Conversation

@nicoloboschi

Copy link
Copy Markdown
Collaborator

Closes the two gaps left in #5540. validate_new_bank_id already guards bank create/ensure, clone and aliases.

Gap 1: whole-bank import skipped the check

submit_bank_import_async and import_bank_async created the target bank (target_bank_id, or the archive manifest's source_bank_id) without calling validate_new_bank_id. A 300-byte id or one with a newline was accepted with a 202 and the bank was created.

Fix:

  • import_bank_async now calls validate_new_bank_id when the target bank does not exist yet. Every restore goes through this method: the HTTP import worker, clone, and the admin CLI import-bank. Existing banks are still never re-checked. The check runs before the restore for both include_bank_config branches.
  • submit_bank_import_async makes the same call (one line) after its "already exists" check, so an HTTP caller gets a 400 at once instead of a failed background operation.

Gap 2: reserve the _ prefix

validate_new_bank_id now refuses a new bank id that starts with _. A store-owned backend that keeps its own bookkeeping objects (_index, _meta, ...) next to a bank's objects needs a part of the name space that no bank can take. Without this rule, each such backend has to invent its own escaping. Existing banks are not affected. No code or test in this repo creates a bank whose id starts with _ (I searched).

The alias request's field description (and the OpenAPI spec and generated clients that copy it) now lists the new rule.

The 192-byte cap is unchanged.

Tests

  • test_document_transfer.py::test_bank_import_refuses_an_invalid_new_bank_id, run for a too-long id, an id with a newline, and a _-prefixed id. It checks that both submit_bank_import_async (HTTP) and import_bank_async (worker and CLI) raise a 400 and that no bank is created.
  • test_ensure_bank_exists_optimization.py::test_invalid_new_bank_id_is_rejected_before_insert gets a new underscore-prefix case: a direct create with a _-prefixed id is a 400 and inserts no row.

Closes #5540

- A whole-bank import created its target bank (the target_bank_id, or the
  archive manifest's source_bank_id) without validate_new_bank_id. The check
  now runs in import_bank_async for a bank that does not exist yet, which
  covers the HTTP restore, clone and the admin CLI import-bank. The HTTP submit
  also checks up front so the caller gets a 400, not a failed operation.
- validate_new_bank_id also refuses a new id starting with `_`: a store-owned
  backend reserves that prefix for its own bookkeeping objects next to a bank's
  objects. Existing banks are not re-checked.

Closes #5540
Fixes verify-generated-files: the alias description's new
'no leading underscore' rule was missing from the Go spec copy.
@nicoloboschi
nicoloboschi merged commit b5ed4c4 into main Oct 16, 2026
117 checks passed
@nicoloboschi nicoloboschi mentioned this pull request Nov 3, 2026
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.

Validate bank_id: unbounded length and control characters are accepted, then break object-store / gRPC backends downstream

1 participant