Skip to content

feat(pass)!: authorize before overwriting secrets - #684

Merged
joe0BAB merged 1 commit into
mainfrom
feat/set-force
Oct 9, 2026
Merged

joe0BAB merged 1 commit into
mainfrom
feat/set-force

Conversation

@joe0BAB

@joe0BAB joe0BAB commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator

set --force asks the engine for the secret it is about to overwrite and stores nothing when access is denied. SetCommand takes the same client options as get, rm and run and returns an error.

Closes docker/secrets-engine-private#729.

Base automatically changed from feat/ls to main October 9, 2026 12:37
@joe0BAB
joe0BAB marked this pull request as ready for review October 9, 2026 12:47

@docker-agent docker-agent left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Assessment: 🟡 NEEDS ATTENTION

Comment thread plugins/pass/commands/set.go Outdated
return wrapKeychainErrors(cmd)
flags.StringArrayVar(&metadata, "metadata", nil, "Non-sensitive key=value metadata (repeatable)")
flags.BoolVarP(&force, "force", "f", false, "Overwrite existing secret if it already exists")
return wrapKeychainErrors(cmd), nil

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[medium] Missing wrapEngineErrors wrapper when --force triggers authorizeAccess

SetCommand now calls authorizeAccess inside RunE when --force is used, which can return a *client.ConnectError. The wrapEngineErrors helper wraps RunE to call withEngineHint on any error, appending an actionable message (e.g. "start Docker Desktop") when a ConnectError carries a hint. Without it, users running set --force against an unreachable engine will see a bare connection error with no guidance.

Both GetCommand (get.go:82) and RmCommand (rm.go:68) already return wrapEngineErrors(wrapKeychainErrors(cmd)). This PR introduced the authorizeAccess call into SetCommand but didn't apply the same outer wrapper.

Suggested change
return wrapKeychainErrors(cmd), nil
return wrapEngineErrors(wrapKeychainErrors(cmd)), nil
Confidence Score
🟢 strong 100/100

}
}
if opts.force {
if force {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[low] Secret value collected from user before authorization check when using --force

When --force is set, the RunE closure fully constructs the secret payload — prompting the user for a value (via prompt.ReadMasked), reading from stdin, unmarshalling, and merging metadata — before calling authorizeAccess at line 108. If authorization is denied, the user has already been prompted to enter a new secret for no effect.

The PR description says "stores nothing when access is denied", which is accurate, but the prompt has already occurred. Moving the authorizeAccess call to before the prompt/read block would make the UX consistent with that intent:

if force {
    if err := authorizeAccess(cmd.Context(), copts, id); err != nil {
        return err
    }
}
// ... then read/prompt for the secret value
Confidence Score
🟢 strong 100/100

set --force asks the engine for the secret it is about to overwrite and
stores nothing when access is denied. SetCommand takes the same client
options as get, rm and run and returns an error.
@joe0BAB
joe0BAB merged commit 4559d63 into main Oct 9, 2026
14 of 15 checks passed
@joe0BAB
joe0BAB deleted the feat/set-force branch October 9, 2026 12:57
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.

3 participants