Safeguard
Application Security•

How do you give TeamCity tokens and users least privilege?

Turn on per-project permissions, assign roles to groups, and issue expiring tokens limited to one project. Notes on the default Project developer role.

Safeguard Security Team
4 min read

Give TeamCity least privilege in three moves: enable per-project authorization, assign roles through groups on the narrowest project, and create access tokens with a limited per-project scope and an expiry date. Review the default Project developer role too, because it carries permissions that can alter build behavior.

Which authorization mode are you in?

TeamCity has two modes. In simple mode there are only three levels: guest, logged-in user and administrator. In per-project mode, users get roles in specific projects or server-wide. Unless configured, the JetBrains docs say simple mode is used in TeamCity Professional and per-project in Enterprise. You change it under Administration, Authentication, by enabling per-project permissions.

In simple mode, every logged-in user maps to the default Project developer role on all projects. That is rarely least privilege for a server holding deploy credentials.

How do roles and permissions work?

A permission authorizes an operation such as running a build. A role is a set of permissions granted in one project or all projects. Permissions granted at project level propagate to subprojects. Roles can be granted to groups, and everyone in the group, directly or through nested groups, receives them.

Default roles include System Administrator, Project Administrator, Project developer, Project Viewer and Agent manager. Project administrators can assign roles only for projects they administer, so a project A administrator cannot grant roles in project B.

What is the catch in Project developer?

The JetBrains documentation notes that by default this role has the permissions to customize build parameters and to change build source code with a custom patch. It says this could give indirect access to altering a configuration or environment per build. In other words, someone who "only runs builds" may be able to change what the build does.

Because role settings are global and editable, you can create a narrower role without those permissions for contributors who only need to start builds and view results.

How should you issue access tokens?

When token authentication is enabled, users can create tokens for scripts and REST calls, sent as a bearer header. Facts from the docs that matter:

  • The token value is shown only at creation and cannot be retrieved later.
  • You can set a time limit so the token is revoked after expiry.
  • By default the scope is "same as current user", so the token carries all of that user's permissions.
  • You can change the scope to "limit per project" and select specific permissions, with read-only and full access presets.
  • Missing permissions may block operations, so test the scope and adjust.

A dedicated service account per integration with a project-limited, expiring token is the least-privilege pattern. A token minted from an administrator's profile is the opposite.

Constructed example

A release script needs to trigger one deploy configuration and read its status. The team creates a service account, adds it to a group holding a custom role with run-build and view permissions in one project, and mints a token scoped to that project with a 90-day expiry. When the script's repo is compromised, the attacker holds a token that can trigger one build, not reconfigure the server.

What to do

  1. Enable per-project permissions and check the mode after upgrades.
  2. List users with System Administrator and remove anyone who does not need it.
  3. Assign roles to groups, not individuals, and review group membership quarterly.
  4. Create a narrower role for contributors that omits custom patch and parameter permissions where possible.
  5. Use service accounts for integrations, with project-limited, expiring tokens.
  6. Enable two-factor authentication, which administrators can turn on server-wide.
  7. Audit token inventory and revoke unused tokens.
  8. Keep TeamCity patched and follow its security bulletins.

Safeguard's dependency scanning and policies can gate what the builds ingest. Server permissions remain TeamCity settings you control.

Quick check

Can I recover a TeamCity token value later?

No. The value is available only at creation, so store it in a secret manager immediately and issue a new token if it is lost.

What scope does a new token get by default?

Same as the current user, meaning it inherits all of that user's permissions. Change it to a limited per-project scope when creating it.

Sources

Last reviewed: 18 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.