Skip to content

Add custom lint rules to enforce domain types over raw strings #98

@bordumb

Description

@bordumb

Problem

Raw strings (&str, String) are used in places where domain types (IdentityDID, CanonicalDid, DeviceDID, Ecosystem, PackageName) should be used. This bypasses validation and makes it easy to pass garbage data through the system. There's no automated enforcement today.

Examples of what we want to catch:

  • did: &str in a function signature → should be IdentityDID or CanonicalDid
  • ecosystem: String in SDK/CLI code → should be Ecosystem enum
  • package_name: String in SDK/CLI code → should be PackageName

The transparency log layer (auths-transparency) deliberately uses String for serialization and is exempt.

Proposal

Layered enforcement, simplest first:

1. just lint with grep checks (do first)

Add a CI-friendly lint target that greps for known anti-patterns:

# Flag DID params passed as raw strings
! grep -rn 'did: &str\|did: String\|_did: &str\|_did: String' \
    --include='*.rs' crates/ \
    | grep -v '// allow-raw-did' \
    | grep -v 'auths-transparency'

Escape hatch: // allow-raw-did comment for intentional cases.

2. Remove new_unchecked() constructors

CanonicalDid::new_unchecked() and IdentityDID::new_unchecked() bypass validation. Audit all call sites, migrate to parse(), then either remove new_unchecked() or gate it behind #[cfg(test)].

3. disallowed-methods in .clippy.toml (optional)

disallowed-methods = [
    { path = "auths_verifier::CanonicalDid::new_unchecked", reason = "Use CanonicalDid::parse() instead" },
    { path = "auths_verifier::types::IdentityDID::new_unchecked", reason = "Use IdentityDID::parse() instead" },
]

4. Custom lint via cargo-marker (future)

For more complex rules (e.g. "any parameter named *_did must have a DID type"), a custom lint plugin. Not worth the setup cost today but good to have as contributor count grows.

Acceptance

  • just lint target exists and runs in CI
  • Grep checks catch did: &str patterns
  • new_unchecked() usage audited and minimized
  • No false positives on auths-transparency (exempt)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions