Repository navigation
fix(management): refuse access key import unless allow_credential_import is true - #840
Open
LeeroyHannigan wants to merge 2 commits into
Open
LeeroyHannigan wants to merge 2 commits into
LeeroyHannigan wants to merge 2 commits into
Conversation
…ort is true An access key import through the management API, and the import-access-key command that calls it, now runs only when the runtime setting allow_credential_import is true. When the catalog has no row for the setting, the server refuses the import with 403, as it does for false. Before this change the server allowed the import when the row was missing. No release writes the row, so every deployment that never set the setting accepted imports. The console settings page already listed the default as false. An import stores an access key ID and secret that the caller chooses. With the feature off by default, only deployments that turn it on accept caller-chosen keys. The setting does not affect keys imported earlier, or the credentials a dev-mode server seeds at startup. The check moves into credential_import_gate. Unit tests cover no row, false, true, other values and a store error. A store error still answers 500, and the refusal message does not change. devtools/run-tests sets allow_credential_import to true with the other runtime settings, before any suite starts. The integration jobs that import keys keep passing, and no test changes the setting while xdist workers run. tests/cli/test-cli-comprehensive.sh enables it before its import step, and the manual test workflows in AGENTS.md and the developer test guide set it before pytest runs. The settings tables, getting-started.md, the admin and deployment guides and the troubleshooting guide state the new default. The upgrade manual tells a deployment that imports keys to run extenddb settings --config extenddb.toml set allow_credential_import true before it upgrades. Signed-off-by: Lee Hannigan <29015211+LeeroyHannigan@users.noreply.github.com>
…port row refuses an access key import The unit tests for credential_import_gate call the function directly, and every integration suite runs with allow_credential_import set to true, because devtools/run-tests stores it before the suites start. Without this test, no test fails if import_access_key stops calling the gate or calls it after the store write. tests/test_allow_credential_import_sqlite.py runs extenddb init --backend sqlite in a temporary directory and serves that deployment on a free port on 127.0.0.1. Its catalog has no allow_credential_import row. As the admin that init created, the test creates an account and a user and posts an access key import for the user. The server must answer 403 with the body "Credential import is disabled (allow_credential_import = false)", and the user's key list must not show the key. The test then runs extenddb settings --config extenddb.toml set allow_credential_import true while the server runs, posts the same import, and expects 201 and the key in the list. After it sets the value to false, a second import gets 403 and the first key still lists. The test uses its own deployment so that it does not change the shared server's settings while other xdist workers import keys. It stops the server and deletes the directory on teardown, also when an assertion fails. init writes its TLS certificate and key under ~/.extenddb, so the extenddb commands run with HOME set inside that directory. The module skips unless extenddb version reports the SQLite backend. In CI the run-integration-sqlite job runs it. The PostgreSQL, MongoDB and Cassandra jobs build their binaries with other backends, so it skips there. Signed-off-by: Lee Hannigan <29015211+LeeroyHannigan@users.noreply.github.com>
LeeroyHannigan
requested review from
amrith,
c33howard,
eliseong,
hitesh96db,
jcshepherd,
navareamol,
pdf-amzn and
robinnsc
as code owners
November 5, 2026 02:29
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
An access key import stores an access key ID and a secret that the caller chooses. After this change, the management API route
POST /management/accounts/{id}/users/{name}/access-keys/importimports a key only when the runtime settingallow_credential_importistrue. Theextenddb manage import-access-keycommand calls this route.falseas the default.falseand any other stored value also refuse the import. The settings CLI and the settings API accept onlytrueorfalsefor this key.Credential import is disabled (allow_credential_import = false). A store error still returns HTTP 500.credential_import_gate, which takes the settings store, so a unit test can give it each case.Test harness:
devtools/run-testssetsallow_credential_importtotruewith the other runtime settings. It does this one time, before any suite starts, so no test changes the setting while xdist workers run. CI runs the pytest,--comprehensiveand Rust integration suites through this script on all four backends.tests/cli/test-cli-comprehensive.sh, and the manual test workflows inAGENTS.mdand the developer test guide, set the value before they import a key.Docs: the settings tables in
docs/differences-from-dynamodb.mdand the admin guide,docs/getting-started.md, the deployment checklist and the troubleshooting guide give the new default. The upgrade manual has a v0.1.15 entry.Why
Each deployment that never set the value accepted imported keys, with an ID and a secret that the caller chose. With import off by default, only a deployment that turns import on accepts them. The server default now also agrees with the console settings page.
Testing done
cargo test -p extenddb-server --lib management: 91 passed. This includes 5 new tests for the gate: no row,false,true, other values (TRUE,True,1,yes, an empty string andtrue) and a store error.cargo fmt --checkandcargo clippy -p extenddb-server --all-targets -- -D warningspass.New
tests/test_allow_credential_import_sqlite.pyrunsinit --backend sqlitein a temporary directory and serves that deployment on a free port on 127.0.0.1. So it does not change the settings of the shared test server. On the new catalog, which has no row for the setting, it does these steps:extenddb settings set allow_credential_import trueruns in the deployment's directory while the server runs. The same import then gets HTTP 201, and the key lists.false, a second import gets HTTP 403, and the first key still lists.It passed 6 times. The
run-integration-sqlitejob runs it, and the jobs that build other backends skip it.Negative controls for the new test: I deleted the gate call, moved it below the store write, and let a missing row allow the import. Each time, the test failed.
devtools/run-tests --filter TestAccessKeyson a new SQLite catalog: with the harness frommain,test_import_access_keyfails with the 403. With the harness from this branch, all 5 tests pass.Merged with fix(storage-mongodb): store each access key ID once #823, which adds 3 tests that import keys: the 8 tests in
TestAccessKeysandTestAccessKeyIdIsStoredOncepass.I did not run
tests/cli/test-cli-comprehensive.sh, because it needs PostgreSQL, the AWS CLI and jq. I ran its two new commands by hand.Checklist
cargo test --workspace)cargo fmt --check)cargo clippy -- -W clippy::pedantic)Storagetrait, auth model, on-diskformat, or public CLI surface, an RFC has been accepted or is linked
below. Otherwise, an ADR captures the decision (link below).
ADR / RFC: n/a. A missing row for one runtime setting now means
false, the default that the console already shows. The name of the setting, its values and the route do not change.Breaking changes
A deployment that imports access keys and never set
allow_credential_importgets HTTP 403 from each import after the upgrade. Before the upgrade, runextenddb settings --config extenddb.toml set allow_credential_import trueon that deployment. The current release accepts the command, and the server reads the value on each import, so a restart is not necessary.By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache License 2.0 and I agree to the Developer Certificate of
Origin (DCO). See CONTRIBUTING.md for details.