Skip to content

feat(data-app)!: copy the password instead of printing it, also after create/deploy --wait (CLI-23) - #813

Merged
soustruh merged 2 commits into
mainfrom
feat/data-app-password-clipboard
Sep 30, 2026
Merged

soustruh merged 2 commits into
mainfrom
feat/data-app-password-clipboard

Conversation

@soustruh

@soustruh soustruh commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

BREAKING: kbagent data-app password does not print the password by default any more. A script that reads .data.password must add --reveal, and a REST client must pass reveal=true. The command no longer uses a Manage API token (KBC_MANAGE_API_TOKEN, --allow-env-manage-token).

What was wrong

  • data-app password required a Manage API token, although the password endpoint of sandboxes-service (GET /apps/{appId}/password) accepts any Storage token of the app's project, and the Keboola UI uses the same call. Under an AI agent there is no terminal for the hidden token prompt, so the command failed unless the user exported the Manage token.
  • The command printed the password to stdout, also with --json. When an AI agent runs kbagent, the password went into the model context and into the chat history.
  • The docs said that the password cannot be rotated. The Keboola UI can reset it.

What changed

  • data-app password uses the project token (static or session).
  • In a terminal it shows the app URL, ui_url (the app page in the Keboola UI, which shows the password under "Open App") and "Press c to copy the password, Enter to finish". The password goes to the OS clipboard only when the user presses c, and it is never printed. The prompt shows only for a process in the foreground and ends after 120 seconds.
  • Without a terminal (an AI agent, CI) or with --json, only --copy copies the password. Without --copy the result has password_delivered_to: null and points to ui_url.
  • --reveal prints the password, as before this change. --copy and --reveal together are INVALID_ARGUMENT. --open opens the app in the browser.
  • data-app create and data-app deploy take the same --copy and --reveal, from one shared definition and one delivery function. They need --wait, because sandboxes-service creates the password while it provisions the app (src/Provisioning/AppProvisioner.php). After a successful --wait in a terminal, the command ends with the same prompt, so deploy --wait on a password app returns after Enter or the timeout. Without a flag and without a terminal the output does not change and kbagent makes no extra API call. When the password read fails after a successful deploy, the result has a warning and the exit code stays 0. Reading the password stays the operation data-app.password: when a policy denies it, --copy and --reveal on create and deploy exit with PERMISSION_DENIED before any API call, and the terminal prompt is skipped. create --dry-run checks the same flags and shows how the password would be delivered.
  • kbagent reads the password only for an app with password authentication (auth_providers[0].type == "password", the same check as in the UI). Another auth type gives VALIDATION_ERROR, and an app without a password yet gives NOT_FOUND.
  • The clipboard tool gets the password on stdin, never as an argument. kbagent tries each clipboard tool it finds and, on WSL, /mnt/c/Windows/System32/clip.exe, also when the Windows PATH is not set in the shell.
  • The REST route GET /data-apps/{project}/{app_id}/password returns the metadata and adds password only with reveal=true.
  • The agent docs tell an agent to recommend that the user runs the command in their own terminal and presses c, to offer --copy, to warn before --reveal that the password then goes into the chat history, and never to read the clipboard or ask for the password in the chat.

Tests

  • tests/test_data_app_password.py runs the real CLI, service and HTTP clients against pytest-httpx, with fakes for the clipboard, the terminal and the browser. A leak test checks on every path that the password is not in stdout, stderr, the DEBUG log or the telemetry event, except with --reveal.
  • Real-terminal tests run the prompt in a child process on a pseudo-terminal: c then Enter, c and Enter in one write, an arrow key, Esc, and Ctrl+C (the terminal mode is restored).
  • The password request carries X-StorageApi-Token, or the bearer and project headers for a session project, and no Manage token header.
  • make check passes.

A manual run on a test project confirmed that the password endpoint accepts the project Storage token. Before the merge, please also run data-app deploy --wait on a password app in a terminal, and data-app password with a limited Storage token and with a session token.

Docs: gotchas.md (since vNEXT), commands-reference.md, data-app-workflow.md, keboola-expert.md, context.py, CLAUDE.md, docs/TUTORIAL.md, docs/web-server-endpoints.md. No version bump, no changelog entry.

Fixes CLI-23

@linear-code

linear-code Bot commented Sep 30, 2026

Copy link
Copy Markdown

CLI-23

@keboola-pr-reviewer-bot keboola-pr-reviewer-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Reviewer error — this is not a verdict. The PR reviewer could not complete this review, so no approval is implied. The failure has been logged for the operator.

reviewer could not complete: reviewer model call errored (subtype=success, api_status=400) after 1/18 turn(s).

Retry with @keboola-pr-reviewer review once the underlying issue clears.

@soustruh

Copy link
Copy Markdown
Contributor Author

@keboola-pr-reviewer review

@keboola-pr-reviewer-bot keboola-pr-reviewer-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Reviewer error — this is not a verdict. The PR reviewer could not complete this review, so no approval is implied. The failure has been logged for the operator.

reviewer could not complete: reviewer model call errored (subtype=success, api_status=400) after 1/18 turn(s).

Retry with @keboola-pr-reviewer review once the underlying issue clears.

@soustruh
soustruh requested review from zajca and removed request for zajca September 30, 2026 06:31

@zajca zajca left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Actionable findings from the automated review.

Comment thread src/keboola_agent_cli/commands/_data_app_password.py
@soustruh
soustruh requested a review from zajca September 30, 2026 08:55

@zajca zajca left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No actionable findings were found by the automated review.

@soustruh
soustruh merged commit d1b11ae into main Sep 30, 2026
4 checks passed
@soustruh
soustruh deleted the feat/data-app-password-clipboard branch September 30, 2026 10:37
@soustruh soustruh mentioned this pull request Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants