Skip to content

Refactor create_signed_attestation to use a params struct (15 positional args → 6) #148

@bordumb

Description

@bordumb

Problem

create_signed_attestation() in crates/auths-id/src/attestation/create.rs takes 15 positional parameters. This is suppressed with #[allow(clippy::too_many_arguments)] but the underlying problem remains:

  • Easy to swap arguments silently (especially the trailing Option<Role>, Option<IdentityDID>, Option<String> which are all Option types)
  • Every new field requires updating 15+ call sites
  • Doc comments for 15 params are hard to maintain
pub fn create_signed_attestation(
    now: DateTime<Utc>,
    rid: &str,
    identity_did: &IdentityDID,
    device_did: &DeviceDID,
    device_public_key: &[u8],
    payload: Option<Value>,
    meta: &AttestationMetadata,
    signer: &dyn SecureSigner,
    passphrase_provider: &dyn PassphraseProvider,
    identity_alias: Option<&KeyAlias>,
    device_alias: Option<&KeyAlias>,
    capabilities: Vec<Capability>,
    role: Option<Role>,
    delegated_by: Option<IdentityDID>,
    commit_sha: Option<String>,        // just added — the 15th
) -> Result<Attestation, AttestationError>

Proposed fix

Introduce an AttestationParams struct for the data fields, keeping only the runtime dependencies (signer, clock, aliases) as positional params:

pub struct AttestationParams {
    pub rid: String,
    pub identity_did: IdentityDID,
    pub device_did: DeviceDID,
    pub device_public_key: Vec<u8>,
    pub payload: Option<Value>,
    pub meta: AttestationMetadata,
    pub capabilities: Vec<Capability>,
    pub role: Option<Role>,
    pub delegated_by: Option<IdentityDID>,
    pub commit_sha: Option<String>,
}

pub fn create_signed_attestation(
    now: DateTime<Utc>,
    params: &AttestationParams,
    signer: &dyn SecureSigner,
    passphrase_provider: &dyn PassphraseProvider,
    identity_alias: Option<&KeyAlias>,
    device_alias: Option<&KeyAlias>,
) -> Result<Attestation, AttestationError>

15 → 6 params. Named fields prevent ordering bugs. Future fields go in the struct with no caller changes.

Call sites to update (~15)

  • crates/auths-sdk/src/domains/signing/service.rs (2 — sign_artifact, sign_artifact_raw)
  • crates/auths-sdk/src/domains/device/service.rs (2)
  • crates/auths-sdk/src/domains/identity/service.rs (1)
  • crates/auths-sdk/src/domains/org/service.rs (1)
  • crates/auths-sdk/src/workflows/org.rs (1)
  • crates/auths-sdk/src/pairing/mod.rs (1)
  • crates/auths-id/src/agent_identity.rs (1)
  • crates/auths-cli/src/commands/org.rs (2)
  • packages/auths-node/src/org.rs (1)
  • packages/auths-python/src/org.rs (1)
  • crates/auths-id/tests/cases/lifecycle.rs (1)

Context

This was identified during #fn-98 (adding commit_sha to signed canonical data). The 15th param was the tipping point. Pure mechanical refactor — zero behavior change.

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