Skip to content

fix: hide shared env and git url credentials in service responses - #10

Merged
agentHits merged 1 commit into
AgentHits-Devfrom
fix/service-response-shared-env-and-git-url
Oct 7, 2026
Merged

agentHits merged 1 commit into
AgentHits-Devfrom
fix/service-response-shared-env-and-git-url

Conversation

@agentHits

Copy link
Copy Markdown
Collaborator

What is this PR about?

Service responses leaked two kinds of secrets.

Shared env. find*ById for all eight service types (application, compose, postgres, mysql, mariadb, mongo, redis, libsql) loads environment.project in full, and the responses returned environment.env and environment.project.env in plain text. That covers .one for every type, plus stop, start, delete and move for applications. Anyone who can see the service got them, including custom roles without environmentEnvVars.read / projectEnvVars.read.

Git URL credentials. application.one and the other application responses returned customGitUrl with the token inside the URL. #5 already fixed this for compose.

Changes:

  • redactDeployableServiceSecrets now masks the userinfo in customGitUrl and hides the environment and project env. redactDatabaseServiceSecrets hides the environment and project env too. Every response that goes through them is covered by default.
  • New redactDeployableServiceSecretsFor / redactDatabaseServiceSecretsFor keep the shared env the caller may read. The .one procedures pass getSharedEnvReadAccess(ctx) (environmentEnvVars.read, projectEnvVars.read), the same permissions the environment router uses. The service env editor reads these fields for shared-variable suggestions, so owners and admins see no change.
  • The router-local redactCustomGitUrl copies in compose and environment are removed: the shared function masks the URL now.
  • Saving the git form with a masked URL keeps the stored URL: saveGitProvider and update already run preserveSecretPlaceholderFields on customGitUrl.

No migrations and no new environment variables; only the dokploy service image changes.

Checks

  • 13 new tests fail on the old code and pass now: redaction helpers, application/compose .one with and without shared env access, the application stop response, and .one for all six databases.
  • __test__/security and __test__/environment: 13 files, 105 tests pass.
  • Full vitest run: 2089 pass, 1 skipped; the 8 failures are only in *.real.test.ts (no local Docker socket).
  • bun run typecheck: 4/4 packages pass.
  • bun run format-and-lint: no errors, no warnings in the changed files.
  • Not done: a manual check in the UI.

Rollout notes

After rollout, with an owner account the service env editor still suggests ${{project.*}} and ${{environment.*}} variables, and the git settings of an application with a tokenized custom URL show __DOKPLOY_REDACTED_SECRET__ in place of the token. Saving that form without changes keeps the original URL.

🤖 Generated with Claude Code

Что:
- redactDeployableServiceSecrets теперь маскирует логин и токен в customGitUrl и скрывает env окружения и проекта (environment.env, environment.project.env). redactDatabaseServiceSecrets тоже скрывает env окружения и проекта. Это касается всех ответов, где есть вложенное окружение.
- Новые варианты redactDeployableServiceSecretsFor и redactDatabaseServiceSecretsFor оставляют те общие переменные, которые вызывающему разрешено читать. Их вызывают .one у application, compose и шести баз. Права берутся из environmentEnvVars.read и projectEnvVars.read (getSharedEnvReadAccess), как в роутере окружений.
- Локальные копии redactCustomGitUrl в роутерах compose и environment удалены: маскирование теперь в общей функции.
- Тесты: модульные для функций скрытия; роутеры application и compose (.one без прав и с правами, ответ stop); шесть баз (.one без прав и с правами).
Зачем:
- find*ById всех восьми типов сервисов подгружает environment.project целиком. Ответы .one, а у приложений ещё stop, start, delete и move, отдавали env окружения и проекта открытым текстом всем, кто видит сервис, в том числе кастомным ролям без права читать общие переменные.
- application.one и другие ответы приложений отдавали customGitUrl с токеном внутри адреса. У compose это закрыл PR #5.
Риски:
- Без environmentEnvVars.read или projectEnvVars.read редактор переменных сервиса больше не подсказывает имена общих переменных: раньше такой пользователь получал и их значения. Владельцы и админы видят всё как раньше.
- Если форма git сохраняется с замаскированным адресом, сохранённый адрес остаётся: saveGitProvider и update уже вызывают preserveSecretPlaceholderFields для customGitUrl.
Проверки:
- Команды и результаты: CI=true bunx vitest run --config __test__/vitest.config.ts __test__/security/secret-redaction.test.ts __test__/security/service-environment-reveal.test.ts __test__/security/database-environment-reveal.test.ts - на старом коде 13 новых тестов падают, после правки все проходят; __test__/security и __test__/environment: 13 файлов, 105 тестов прошли. Полный прогон: 2089 прошли, 1 пропущен, 8 упали только в *.real.test.ts (нет сокета Docker Desktop). bun run typecheck - 4/4 без ошибок. bun run format-and-lint - 0 ошибок, в изменённых файлах нет предупреждений.
- Ограничения: в интерфейсе вручную не проверялось; на dev не выкатывалось.

What:
- redactDeployableServiceSecrets now masks the login and token in customGitUrl and hides the environment and project env (environment.env, environment.project.env). redactDatabaseServiceSecrets hides the environment and project env too. This covers every response that carries the nested environment.
- New variants redactDeployableServiceSecretsFor and redactDatabaseServiceSecretsFor keep the shared env the caller may read. The .one procedures of application, compose and the six databases use them. Access comes from environmentEnvVars.read and projectEnvVars.read (getSharedEnvReadAccess), as in the environment router.
- The local redactCustomGitUrl copies in the compose and environment routers are removed: the shared function masks the URL now.
- Tests: unit tests for the redaction helpers; application and compose routers (.one with and without access, the stop response); six databases (.one with and without access).
Why:
- find*ById for all eight service types loads environment.project in full. The .one responses, plus stop, start, delete and move for applications, returned the environment and project env in plain text to anyone who can see the service, including custom roles without permission to read shared env.
- application.one and other application responses returned customGitUrl with the token inside the URL. PR #5 already fixed this for compose.
Risks:
- Without environmentEnvVars.read or projectEnvVars.read, the service env editor no longer suggests shared variable names: such users used to get their values as well. Owners and admins see everything as before.
- Saving the git form with a masked URL keeps the stored URL: saveGitProvider and update already call preserveSecretPlaceholderFields for customGitUrl.
Checks:
- Commands and results: CI=true bunx vitest run --config __test__/vitest.config.ts __test__/security/secret-redaction.test.ts __test__/security/service-environment-reveal.test.ts __test__/security/database-environment-reveal.test.ts - on the old code 13 new tests fail, after the fix all pass; __test__/security and __test__/environment: 13 files, 105 tests passed. Full run: 2089 passed, 1 skipped, 8 failed only in *.real.test.ts (no Docker Desktop socket). bun run typecheck - 4/4 clean. bun run format-and-lint - 0 errors, no warnings in the changed files.
- Limitations: not checked by hand in the UI; not deployed to dev.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@agentHits
agentHits merged commit 0950ba9 into AgentHits-Dev Oct 7, 2026
4 checks passed
@agentHits
agentHits deleted the fix/service-response-shared-env-and-git-url branch October 7, 2026 03:48
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.

1 participant