Skip to content

test(api): Harden v3 authorization and authentication coverage - #1166

Open
ShJ-code wants to merge 5 commits into
openstack-experimental:mainfrom
ShJ-code:fix/api-test-quality-994-review
Open

test(api): Harden v3 authorization and authentication coverage#1166
ShJ-code wants to merge 5 commits into
openstack-experimental:mainfrom
ShJ-code:fix/api-test-quality-994-review

Conversation

@ShJ-code

Copy link
Copy Markdown
Collaborator

Summary

Closes #994.

This PR builds on the endpoint coverage introduced by #993 and reuses the API
test infrastructure from #992 to strengthen the v3 authorization and
authentication test suite.

It adds:

  • Authorization matrices for domains, projects, users, credentials, roles,
    implied roles, assignments, and tokens.
  • Positive, policy-denial, missing-token, invalid-token, and revoked-token
    coverage.
  • Token ownership and rescope tests, including authentication-chain
    preservation and unauthorized-scope rejection.
  • Coverage for password, token, EC2, and routed authentication-plugin paths.
  • Shared scoped-user, raw-request, assignment, token, and authentication-plugin
    fixtures.
  • Guarded cleanup for requests that unexpectedly pass authorization.
  • Isolated SDK authentication state for live API tests, preventing stale tokens
    from a previous database from being reused.

The v3 integration binary now contains 251 tests, meeting the 250+ target from
#994.

The review also identified that malformed Fernet and JWS credentials were
surfacing as HTTP 500 responses. They are now classified as invalid
credentials and return HTTP 401. Operational provider failures retain their
existing error status and CADF reason.

OPA policy tests were aligned with the serialized credentials.system field,
including explicit rejection of system scopes other than all.

Test plan

Verified with:

cargo nextest run --profile api -p test_api \
  --test integration_api_v3 --no-fail-fast

251 tests run: 251 passed, 0 skipped
cargo test -p test_api --lib

29 passed
cargo test -p openstack-keystone-token-driver-fernet

41 passed, 1 ignored
cargo test -p openstack-keystone-token-driver-jws

9 passed
cargo test -p openstack-keystone --lib \
  api::v3::auth::token::common::tests

7 passed
opa test policy

PASS: 366/366

The following checks also passed:

cargo fmt --all -- --check
cargo check -p openstack-keystone --message-format=short
cargo check -p test_api --tests --message-format=short
committed upstream/main..HEAD
git diff --check upstream/main..HEAD

The diff was additionally checked for newly introduced unsafe blocks,
unwrap(), expect(), and println!; none were found.

Security review checklist

Required if this diff touches authentication, scope, delegation, tokens,
credentials, EC2, trusts, application credentials, or OPA policy input.

Delete this section entirely if it doesn't apply. See
doc/src/security.md §7 for the full context
behind each item.

  • No delegation or authorization decision was changed to read mutable token
    scope instead of the immutable authentication chain. Token rescope tests
    verify that the authentication context is preserved. (I1/I2)
  • No new delegation-sensitive policy rule was added. Existing delegation
    projection, delegated_project_id, and scope-drift requirements are
    unchanged. (I2/I3)
  • No new delegated redemption path or scope shape was added. Effective-role
    bounding remains unchanged. (I4)
  • No new ScopeInfo variant or native authentication method was added.
    Existing scope-boundary and security-context resolution paths are exercised
    end-to-end. (I5, Gate J)
  • No new lookup by a client-derived key was added. (I6)
  • No secrets or decrypted credential blobs were added to OPA input. (I7,
    Gate I)
  • No new list endpoint was added. Existing collection behavior and per-item
    authorization requirements remain unchanged. (I8)
  • Credential list tests require an unprivileged caller to filter by its own
    user_id; they do not permit an unfiltered collection scan and rely on the
    same filter used by the persistence driver. (I8a)
  • Request-supplied scope cannot broaden a narrow authentication method.
    Negative rescope tests verify unauthorized domains are rejected and the
    original authentication chain is preserved. (I5)
  • Negative tests cover missing, malformed, expired, and revoked tokens,
    policy denials, cross-user access, project/system scope isolation, and
    unauthorized rescope.
  • Token rescope tests exercise
    ValidatedSecurityContext::new_for_scope() through the live API rather than
    testing only its inner helpers.

@gtema gtema left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correctness (top priority):

[crates/token-driver-jws/src/lib.rs:125](https://github.com/openstack-experimental/keystone/blob/main/crates/token-driver-jws/src/lib.rs#L125) — decode()'s key-rotation candidate loop now uses ? on to_decoding_key() failures instead of the old continue/last_err pattern, so a failure on the primary key aborts the whole loop and never falls back to active.previous. This breaks the documented "multi-generational tolerance during a rotation's grace window" — a corrupt/unparsable primary key would reject otherwise-valid tokens signed with a still-good previous key. Unguarded by any test.
[crates/api-types/src/error_conv.rs:579](https://github.com/openstack-experimental/keystone/blob/main/crates/api-types/src/error_conv.rs#L579) — the blanket From<TokenProviderError> impl wasn't updated for the new InvalidToken/Expired/TokenRevoked variants; the 500→401 fix only lives in a local wrapper in [auth/token/common.rs](https://github.com/openstack-experimental/keystone/blob/main/auth/token/common.rs). Harmless today (all current callers discard the error type first) but a latent trap for future callers using ? directly.

Reuse/simplification:
3. Two test files locally reimplement assert_raw_unauthorized instead of the shared helper this PR itself adds.
4. credential/authorization.rs and auth/token/authorization.rs reimplement provision_fixture_pair's cleanup-on-failure pattern inline (4 copies total).

Minor:
5. Collapsing decode errors into InvalidToken loses diagnostic detail in operator logs (show.rs/delete.rs).
6. The PR title claims to fix "system scope input contracts" but the only Rego change is inside an already-dead, commented-out block — the real unreachable-branch issue documented elsewhere in policy/ is untouched.

@ShJ-code
ShJ-code force-pushed the fix/api-test-quality-994-review branch 2 times, most recently from be6fdfe to d5f8ae5 Compare August 14, 2026 06:06
Add reusable scoped-user and raw-request helpers.

Add token, assignment, and auth-plugin fixtures for the matrices.

Disable the SDK auth cache so fresh API runs cannot reuse stale tokens.

Keep revocation tests isolated from concurrent sessions.

Signed-off-by: ShJ-code <sihao_jiang@outlook.com>
Add positive and policy-denial matrices for domains and projects.

Cover user and credential ownership boundaries.

Exercise invalid, missing, and revoked tokens.

Keep cleanup guarded on unexpected authorization success.

Signed-off-by: ShJ-code <sihao_jiang@outlook.com>
Add positive, forbidden, and unauthenticated role matrices.

Cover project and system grants across user scope boundaries.

Exercise implied-role authorization for every operation.

Signed-off-by: ShJ-code <sihao_jiang@outlook.com>
Classify malformed Fernet and JWS credentials as invalid tokens.

Return 401 for invalid, expired, and revoked token credentials.

Preserve operational provider errors and CADF reasons.

Signed-off-by: ShJ-code <sihao_jiang@outlook.com>
Exercise password, token rescope, EC2, and routed plugin methods.

Cover ownership, policy denial, invalid credentials, and revocation.

Verify authentication-chain preservation across authorized rescope.

Signed-off-by: ShJ-code <sihao_jiang@outlook.com>
@ShJ-code
ShJ-code force-pushed the fix/api-test-quality-994-review branch from d5f8ae5 to 2a362a6 Compare August 14, 2026 15:34
@ShJ-code
ShJ-code requested a review from gtema August 14, 2026 15:34
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.

[Phase 3] API test quality: 401/403/scope isolation & auth-method matrix (CLAUDE.md compliance)

2 participants