Checklist
Description
In --format=directory, client grant filenames are built from client name + API name only
(src/context/directory/handlers/clientGrants.ts). subject_type is not included.
A client holding both a client and a user grant on the same audience therefore maps both
grants to one file — the second write silently overwrites the first. No error or warning is
emitted; the dump only validates that the generated name is non-empty.
This contradicts the import side, where a grant's identity is (client_id, audience,
subject_type) per the identifiers list in src/tools/auth0/handlers/clientGrants.ts, which
also has dedicated DELETE + CREATE handling because subject_type is immutable.
Consequence: the lost grant is absent from the export and becomes a deletion candidate on the
next import (removed outright when AUTH0_ALLOW_DELETE is enabled).
Separately, the clientGrants handler never prunes stale files, unlike connections. A grant
deleted from the tenant keeps its file and is recreated on the next import.
Expectation
Every client grant on the tenant should produce its own file, and a round-trip
(export → import) should be lossless. Files for grants no longer on the tenant should not
persist and be re-imported.
Reproduction
- On a tenant, give one client two grants on the same audience — one with
subject_type "client", one with subject_type "user".
- a0deploy export -c config.json -f directory -o ./out
- Inspect ./out/grants/ — only one file exists for that client/audience pair, containing
whichever grant was written last. Total file count is one fewer than the number of
grants on the tenant.
Deploy CLI version
8.43.0
Node version
24.18.0
Checklist
Description
In
--format=directory, client grant filenames are built from client name + API name only(src/context/directory/handlers/clientGrants.ts).
subject_typeis not included.A client holding both a
clientand ausergrant on the same audience therefore maps bothgrants to one file — the second write silently overwrites the first. No error or warning is
emitted; the dump only validates that the generated name is non-empty.
This contradicts the import side, where a grant's identity is (client_id, audience,
subject_type) per the
identifierslist in src/tools/auth0/handlers/clientGrants.ts, whichalso has dedicated DELETE + CREATE handling because subject_type is immutable.
Consequence: the lost grant is absent from the export and becomes a deletion candidate on the
next import (removed outright when AUTH0_ALLOW_DELETE is enabled).
Separately, the clientGrants handler never prunes stale files, unlike connections. A grant
deleted from the tenant keeps its file and is recreated on the next import.
Expectation
Every client grant on the tenant should produce its own file, and a round-trip
(export → import) should be lossless. Files for grants no longer on the tenant should not
persist and be re-imported.
Reproduction
subject_type "client", one with subject_type "user".
whichever grant was written last. Total file count is one fewer than the number of
grants on the tenant.
Deploy CLI version
8.43.0
Node version
24.18.0