Skip to content

A credential provider plugin for trusted publishing #15743

@weihanglo

Description

@weihanglo

Problem

Trusted publishing is generally available today. It hardens the CI publish workflow a lot. However, cargo publish by default performs a verification for your package before the actual crates.io publish/upload. Cargo currently compiles the package as part of the verification step. That means the lifetime of the temporary publish token generated by crates-io-auth-action lives unnecessarily longer than the actual publish step .

The situation might get worse when -Zpackage-workspace (be able to publish the entire workspace) is stabilized.

The situation is a lot better than old days, we can look at what Cargo can do to help minimize the life time of the publish token, hardening the security even more.

Proposed Solution

A solution around leveraging Cargo's credential provider has been brought up: rust-lang/rfcs#3691 (comment).

Basically we can create a credential provider plugin that hooks into the publish request, and prepare the token right before the publish. Let me repost the flowchart here

sequenceDiagram
    participant D as Developer
    participant Cargo
    participant COP as cargo-oidc-provider<br/>(built-in or installed from GH Action)
    participant OIDC as GH OIDC Provider
    participant C as crates.io
    
    D->>Cargo: 1. Trigger release workflow
    rect rgb(253, 253, 150)
    note right of Cargo: cargo publish
    Cargo->>+COP: 0. Read operation<br/>(not important to crates.io)
    COP-->>-Cargo: Respond to Read operation
    Cargo-->>Cargo: Build artifact
    Cargo->>+COP: 1. Publish operation

    COP->>+OIDC: 2. Authenticate & request signed ID token
    OIDC-->>-COP: 3. Return signed ID token
    COP->>+C: 4. Send ID token & request access token
    C-->>C: 5. Verify validity of ID token using GHA OIDC's public keys
    C-->>-COP: 6. Return temporary access token
    COP-->>-Cargo: 7. Respond to Publish operation
    Cargo->>+C: 8. Publish artifact with access token
    C-->>-Cargo: Publish success
    end

    rect rgb(253, 253, 150)
    note right of Cargo: cargo logout<br/>(remote logout not implemented)
    Cargo->>+C: 9. Request revocation of access token
    C-->>-Cargo: Confirm revocation of access token
    
    end
Loading

Notes

A immediate problem of this approach is that the workflow of publish doesn't have a post action for us to revoke the token. We might need an extra post-publish hook. Unsure if that requires a version bump of the protocol (I guess yes?)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-credential-providerArea: credential provider for storing and retreiving credentialsA-interacts-with-crates.ioArea: interaction with registriesC-feature-requestCategory: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`S-needs-designStatus: Needs someone to work further on the design for the feature or fix. NOT YET accepted.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions