Skip to content

Generate passwords and confirm PROD updates in service_update_password - #250

Merged
nathanjcochran merged 5 commits into
mainfrom
nathan/mcp-password-confirmation
Sep 30, 2026
Merged

nathanjcochran merged 5 commits into
mainfrom
nathan/mcp-password-confirmation

Conversation

@nathanjcochran

@nathanjcochran nathanjcochran commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

Makes the service_update_password MCP tool safer by having it generate passwords itself and confirm PROD updates with the user.

  • Removed the password parameter; the tool now always generates the password. A password passed as an argument is either invented by the model or typed into the chat by the user, so it ends up in the model's context. Collecting it through an elicitation form instead would still expose it to session transcripts and the MCP client, and the MCP spec says servers MUST NOT request passwords through form elicitation. Users who want a specific password can still set one with tiger service update-password.
  • Added a with_password option to include the generated password in the result, matching service_create and service_get. It's off by default. When it's off and the new password isn't saved, because saving fails or password storage is disabled, the result warns that nobody has the password.
  • Added an elicitation prompt for PROD services, modeled on service_delete: the user types the service ID back to confirm. A client that can't prompt gets an error telling the agent to ask the user to run the CLI command instead.
  • Moved the typed-ID confirmation helpers into a new internal/mcp/elicitation.go, so all tools share them.
  • Error messages now tell the agent to ask the user to run a CLI command, rather than telling the agent to run it, so agents don't try to work around the MCP server by running the CLI themselves.
  • Moved GenerateSecurePassword from internal/util to internal/common, since it's specific to database passwords rather than a generic helper (like GenerateServiceName). It's also now a var so tests can stub it. GetService also moved from internal/common/replica.go into internal/common/service.go, where it belongs.

@nathanjcochran nathanjcochran self-assigned this Sep 28, 2026
@nathanjcochran
nathanjcochran marked this pull request as ready for review September 28, 2026 22:29
@nathanjcochran
nathanjcochran requested a review from a team as a code owner September 28, 2026 22:29

@Askir Askir 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.

I will say I am not too fond of the elicitation stuff yet basically haven't used it ever but maybe i just use MCPs too little.
But generally looks good 👍

Comment thread internal/mcp/utils.go
// setWithPasswordSchemaProperties sets common with_password schema properties
func setWithPasswordSchemaProperties(schema *jsonschema.Schema) {
schema.Properties["with_password"].Description = "Whether to include the password in the response and connection string. NEVER set to true unless the user explicitly asks for the password."
schema.Properties["with_password"].Description = "Whether to include the password in the response. NEVER set to true unless the user explicitly asks for the password."

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.

I think the other tools with this flag actually still output the connection string 🤔

@nathanjcochran nathanjcochran Sep 30, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, the other tools do still output the connection string, but the connection string is part of "the response", so the message is still accurate imo. I just wanted to make it generic enough to also be used for tools that don't output a connection string. For the tools that do, the connection string field description itself carries an explanation of how the with_password parameter affects it (see here), so I don't think we're really losing any clarity here.

@nathanjcochran

nathanjcochran commented Sep 30, 2026 •

Copy link
Copy Markdown
Member Author

I will say I am not too fond of the elicitation stuff yet basically haven't used it ever but maybe i just use MCPs too little.

Yeah, it's a tough call, and I frankly have mixed feelings too. We decided to add it as an extra safety precaution for PROD services, because we previously couldn't even come to agreement about whether it made sense to provide a service_delete tool at all (many people wanted it for the sake of agentic fork-test-delete workflows, but other people had concerns about the potential for a rogue agent to autonomously delete a production database). Adding service_delete with an elicitation confirmation prompt that forces a human to be in the loop (for PROD services) felt like a decent middle ground that allowed us to provide the tool and make deleting DEV services easy, but also assuage people's concerns about PROD services.

Fwiw, we have also seen real issues with agents abusing these tools: we had an internal report of someone's agent deciding to autonomously change a service's password when it failed to connect to it, which could have been very bad for a production service. So adding the same confirmation prompt for PROD password updates likewise felt like a valuable safeguard.

The flip side is that we do already have read-only mode, which protects people's production services, and most coding agent harnesses likewise ask for confirmation before executing MCP tools (though most people are probably just using auto-mode these days, which I suspect would let these kinds of calls through). The MCP tools are also marked as "destructive", which many harnesses use to determine if they should ask for additional confirmation before proceeding. So in some ways, it feels like we're re-implementing features that belong in the coding agent/harness, rather than in the MCP server, and aren't trusting people to make their own choices about the level of safety they want.

Still, doing it in the MCP server is the only way we can guarantee there's always a human-in-loop for these kinds of destructive actions, which I think is worthwhile from a product safety perspective. Additionally, I don't expect people to be deleting production services, or rotating their passwords, very often (and DEV services do not have the same confirmation requirement), so I don't expect it to be a major source of friction for most agentic workflows. It's still definitely something we should keep an eye on, though.

@nathanjcochran
nathanjcochran merged commit ad7724f into main Sep 30, 2026
2 of 4 checks passed
@nathanjcochran
nathanjcochran deleted the nathan/mcp-password-confirmation branch September 30, 2026 19:08
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.

2 participants