Repository navigation
Description
What DynamoDB does
Measured 2026-11-03 in us-east-1. Each request is an ImportTable with S3BucketSource naming a bucket that does not exist and InputFormat DYNAMODB_JSON. Its TableCreationParameters has pk (S) as the HASH key and PAY_PER_REQUEST, and its TableName is a table ARN in another account, arn:aws:dynamodb:us-east-1:<other account>:table/<T>. Each caller sent it once with an account that exists and once with one that does not, and got the same answer both times:
| Caller | Answer |
|---|---|
| an admin | AccessDeniedException "User: is not authorized to perform: dynamodb:ImportTable on resource: arn:aws:dynamodb:us-east-1::table/arn:aws:dynamodb:us-east-1::table/" |
| no policy | the same |
The message has no "because ..." clause. A table ARN in the caller's own account was not sent.
What ExtendDB does
The same requests were replayed on 2026-11-03 against a SQLite server built from e3b0f96 (the head of #509), which has no [import] paths. Both accounts gave the same answers:
| Caller | Answer |
|---|---|
a user allowed dynamodb:* on * |
ValidationException "Import is disabled. Configure [import] paths in extenddb.toml to enable." |
| no policy | AccessDeniedException with the service's message followed by " because no identity-based policy allows the dynamodb:ImportTable action" |
The allowed user passes the IAM decision and the engine answers.
Code path
- At e3b0f96,
authz_targetsauthorizesImportTableonarn:aws:dynamodb:<region>:<caller account>:table/<value as written>(597c1dc). An Allow on*matches that resource. - On main (03baa32) the resource is
table_resource_arnof the value, which reduces a table ARN totable/<T>in the caller's account (crates/server/src/authz_resource.rs:551-558and:370-385), so the no-policy denial on main names that ARN instead (read from the code, not replayed). deny_messageadds "because no identity-based policy allows the action" to a denial that no explicit Deny caused (crates/server/src/authorization.rs:287-301on main).- fix(server): name the supplied ARN in a denial #509's cross-account refusal skips
ImportTable, because the service reads the table name as a name (findincrates/server/src/authz_resource/cross_account.rs). handle_import_tableanswers "Import is disabled" when no import paths are configured (crates/engine/src/import_export.rs:43-47). With import paths and a readableFileSource, it passes the value as written tocreate_tablewithout theCreateTablename checks (:80-85, ImportTable creates a table under a name CreateTable refuses #771).
Expected
An ImportTable whose TableCreationParameters.TableName is a table ARN gets the service's AccessDeniedException, with no reason clause, for both callers and before the engine runs. The answer for these values was not measured: a table ARN in the caller's own account, an index or stream ARN, and a value that starts with arn: but is not an ARN.
Related
#771 asks ImportTable to refuse the names CreateTable refuses, with the service's ValidationExceptions. For a table ARN the service answers this AccessDeniedException instead, to an admin as well as to a caller with no policy, so the ARN case has to be answered before #771's name check.
Activity