Keep TeamCity secrets out of repositories, environment variables and build logs. Store them in password-type parameters, enable a custom encryption key, keep versioned settings in a separate locked repository, and move high-value credentials to an external secrets manager. Then review who can read the server's data directory and build settings.
What does JetBrains say to keep out of the pipeline?
The TeamCity security notes name three places to keep credentials out of: repositories on services such as GitHub and GitLab, environment variables (often logged or shared with third-party monitoring), and the build log. For versioned settings in Kotlin DSL or XML, they say never store credentials in the configuration files, and use tokens instead.
This is the daily failure mode: a developer exports a token in a build step so a script works, and the value lands in a log that many people can read.
What do password-type parameters do, and where do they stop?
Typed parameters with the password type keep values out of the web UI and mask them with asterisks in the build log. The notes add that the values are encrypted at rest. They also say this often does not give a high enough level of security, and suggest a tool such as HashiCorp Vault to manage and rotate credentials.
Masking is a courtesy, not a boundary. A build step can still transform a value, for example by encoding it, and print the result.
Who can still read your secrets?
This is the part to read twice. According to the notes:
- Anyone who can change code used in builds, including committers on branches or pull requests that TeamCity builds, can retrieve settings of the configurations where the builds run, including the values of password fields.
- By default, the system stores external passwords in scrambled form with a fixed key, so anyone with access to the server file system or database can recover them. A custom encryption key replaces that with your own key.
- Read access to the data directory exposes all settings, including configured passwords. Read access to build artifacts in the data directory gives access to password parameter values used in builds.
- Private SSH keys uploaded to the server are stored on disk in plain text, so use keys already encrypted with a passphrase.
What about versioned settings?
If settings live in the same repository as the source code, a malicious developer can add a build step that prints or sends the project's passwords. JetBrains suggests a separate repository that only a limited group can commit to.
Constructed example: a team keeps its Kotlin DSL in the app repo. A contractor with branch access adds a step that writes a deploy token to an artifact, and the token is downloadable by any build user. Moving the settings to a restricted repo, and the token to a vault, closes both holes.
What to do
- Search build logs and artifacts for credentials and rotate any you find.
- Convert every secret parameter to the password type.
- Enable a custom encryption key and store the key outside the server data directory.
- Move deployment credentials to an external secrets manager with short-lived values where possible.
- Put versioned settings in a separate repository with limited commit rights.
- Use auto-expiring access tokens for the REST API, from a dedicated low-permission user.
- Restrict OS permissions on the data directory and server logs.
- Treat your CI server as high value: Safeguard's secrets scanning can check repositories and configuration files for committed credentials, which catches one source of leaks before they reach CI.
How do you test that it worked?
After changes, run a dry check. Create a throwaway password parameter, echo a transformed version in a test build on a non-production project, and confirm who can see the output. Then search recent logs and artifacts for known token prefixes. Finally, ask a developer with the default role to try retrieving a secret from a project they should not reach.
Quick check
Are password parameters enough on their own?
No. They are masked and encrypted at rest, but JetBrains says that often is not enough and suggests a secrets management tool.
Why enable a custom encryption key?
Without it, stored passwords are only scrambled with a fixed key and can be retrieved by someone with file system or database access.
Sources
Last reviewed: 18 October 2026.