local_ydb_prepare_auth_config
Generate a hardened YDB config from the current static-node config. Use before writing dynamic auth config and applying auth hardening.
Instructions
Generate a hardened YDB config from the current static-node config. Use before local_ydb_write_dynamic_auth_config and local_ydb_apply_auth_hardening; without confirm=true this returns the planned write only.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| profile | No | Named profile from local-ydb.config.json. Defaults to config.defaultProfile. | |
| configPath | No | Explicit local-ydb config file path to load for this tool call. Useful when the MCP server should pick up a different config without restart. | |
| confirm | No | Must be true to write the hardened config file. Omit or false for plan-only output. | |
| configHostPath | No | Host path for the generated hardened config. Defaults to profile.authConfigPath when present. | |
| sid | No | SID to place into viewer, monitoring, administration, and register_dynamic_node_allowed_sids. Defaults to profile.dynamicNodeAuthSid or root@builtin. |
Implementation Reference
- The core handler: generates a hardened YDB config from the current static-node config, enforcing user token requirements, setting allowed SIDs for viewer/monitoring/administration/dynamic registration, and optionally extracting the root password. Uses Ruby to parse/modify YAML via docker exec.
export async function prepareAuthConfig( ctx: ToolkitContext, options: MutatingOptions & { configHostPath?: string; sid?: string } = {} ) { const configHostPath = options.configHostPath ?? ctx.profile.authConfigPath; const sid = options.sid ?? ctx.profile.dynamicNodeAuthSid ?? "root@builtin"; const rootSid = ctx.profile.rootUser; if (!configHostPath) { return planOnly( ctx, "Prepare auth config requires configHostPath directly or through the selected profile.", "medium", [], ["No changes."], ["Provide configHostPath and rerun."] ); } const rootPasswordFile = ctx.profile.rootPasswordFile ?? ""; const targetCommand = commandForStaticGeneratedConfigPath(ctx.profile.staticContainer); const script = [ "set -euo pipefail", `install -d -m 0700 ${shellQuote(dirname(configHostPath))}`, rootPasswordFile ? `install -d -m 0700 ${shellQuote(dirname(rootPasswordFile))}` : ":", "tmp=$(mktemp)", "trap 'rm -f \"$tmp\"' EXIT", `target=$(${targetCommand})`, `docker exec ${shellQuote(ctx.profile.staticContainer)} cat "$target" > "$tmp"`, [ "ruby -ryaml -e", shellQuote([ "config = YAML.load_file(ARGV[0])", "domains = config.fetch(\"domains_config\")", "security = domains[\"security_config\"] ||= {}", "allowed_sids = [ARGV[2], ARGV[4]].reject(&:empty?).uniq", "security[\"enforce_user_token_requirement\"] = true", "security[\"viewer_allowed_sids\"] = allowed_sids", "security[\"monitoring_allowed_sids\"] = allowed_sids", "security[\"administration_allowed_sids\"] = allowed_sids", "security[\"register_dynamic_node_allowed_sids\"] = allowed_sids", "File.write(ARGV[1], YAML.dump(config))", "File.chmod(0600, ARGV[1])", "if !ARGV[3].empty?", " root = Array(security[\"default_users\"]).find { |user| user[\"name\"] == \"root\" }", " raise \"root password not found in security_config.default_users\" unless root && root[\"password\"]", " File.write(ARGV[3], \"#{root[\"password\"]}\\n\")", " File.chmod(0600, ARGV[3])", "end" ].join("; ")), "\"$tmp\"", shellQuote(configHostPath), shellQuote(sid), shellQuote(rootPasswordFile), shellQuote(rootSid) ].join(" ") ].join("\n"); return runMutating(ctx, { summary: `Prepare hardened auth config at ${configHostPath}.`, risk: "medium", specs: [bash(script, { redactions: pathRedactions(configHostPath, rootPasswordFile) })], rollback: [ `rm -f ${configHostPath}`, ...(rootPasswordFile ? [`rm -f ${rootPasswordFile}`] : []) ], verification: [ `test -s ${configHostPath}`, ...(rootPasswordFile ? [`test -s ${rootPasswordFile}`] : []) ] }, options); } - Input schema definition for the tool, declaring optional configHostPath and sid parameters plus standard profile/configPath/confirm properties.
export function prepareAuthConfigSchema(): Tool["inputSchema"] { return { type: "object", properties: { profile: profileProperty(), configPath: configPathProperty(), confirm: confirmProperty("write the hardened config file"), configHostPath: { type: "string", description: "Host path for the generated hardened config. Defaults to profile.authConfigPath when present.", }, sid: { type: "string", description: "SID to place into viewer, monitoring, administration, and register_dynamic_node_allowed_sids. Defaults to profile.dynamicNodeAuthSid or root@builtin.", }, }, additionalProperties: false, }; } - Zod validation schema for the tool's arguments, extending MutatingArgs with optional configHostPath and sid fields.
export const PrepareAuthConfigArgs = MutatingArgs.extend({ configHostPath: z.string().optional(), sid: z.string().optional(), }); - packages/mcp-server/src/tools/registry.ts:472-482 (registration)Tool registration in the MCP registry: defines the tool name, group (auth), description, input schema, annotations, and handler that delegates to prepareAuthConfig from @local-ydb-toolkit/core.
defineTool({ group: "auth", name: "local_ydb_prepare_auth_config", description: "Generate a hardened YDB config from the current static-node config. Use before local_ydb_write_dynamic_auth_config and local_ydb_apply_auth_hardening; without confirm=true this returns the planned write only.", inputSchema: prepareAuthConfigSchema(), annotations: mutatingAnnotations(), handler: withContext(PrepareAuthConfigArgs, (context, parsed) => prepareAuthConfig(context, parsed), ), }),