Skip to content

dpp-types: unrecognized API-key scope strings fail open to Admin; retention policy has no lower bound #21

Description

@LKSNDRTMLKV

Static read-through audit of crates/dpp-types. The crate is exclusively types + trait ports (no unsafe, no unwrap/panic, no TODO markers). Two verified findings.

1. Unrecognized scope values fail open to full Admin

Location: src/api_key.rs:62-71 (ApiKeyScope::from_scopes)
Issue: The match chain is is_empty() || contains "admin" → Admin, else contains "write" → Write, else contains "read" → Read, else — the final catch-all — Admin. This is not limited to the documented empty-array back-compat case; it catches any unrecognized value. This directly contradicts the enum's own doc comment, which frames Admin as the deliberately-opt-in risky tier and Read/Write as the least-privilege path.
Failure scenario: A scopes array like ["superuser"], a typo, a case mismatch, or any future scope string not yet in this match falls through every branch to the trailing else => Admin, silently granting full admin (key management + operator-config mutation) instead of failing safe to least privilege. Trigger: any row in the scopes TEXT[] column that isn't exactly {admin}, {write}, or {read} — manual edit, migration bug, or a future scope name added to the DB before this match is updated. (See also the related findings in dpp-dal and dpp-vault — this is a systemic gap across the scope-enforcement chain.)

2. Retention policy accepts non-positive values

Location: src/operator.rs:187-189 (UpdateOperatorConfig::apply)
Issue: retention_policy_days is copied straight from the PATCH body onto OperatorConfig with no range check, despite its own doc comment describing it as an ESPR-driven minimum-retention invariant (default 3650 = ~10 years).
Failure scenario: {"retentionPolicyDays": -1} in a PATCH request body passes through unchanged, leaving a config that violates the documented minimum-retention guarantee with no rejection at this layer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcomplianceRegulatory/compliance correctness issuesecuritySecurity-relevant issue

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions