Security best practices
TFS 2017 | TFS 2015 | TFS 2013
Security should always be your topmost concern when you’re working with information and data, especially when you're working in a cloud-based solution, like Azure DevOps Services. Microsoft keeps the underlying cloud infrastructure secure, but it's up to you to configure security in Azure DevOps.
You don't have to implement best practices when using Azure Devops, but doing so will likely help you have a better, more secure experience. We've gathered some best practices for keeping your Azure DevOps environment secure, with the following goals in mind:
- Properly scope service accounts, service connections, and permissions
- Maintain tight control of administrators and service account groups
- Manage security with security groups, policies, and settings at the organization/collection, project, or object level
- Secure services, like Azure Artifacts, Azure Boards, Azure Pipelines, Azure Repos, Azure Test Plans, and Azure DevOps in general.
Scope service accounts
- Ensure service accounts have zero interactive sign-in rights.
- Restrict service account privileges to the bare minimum necessary.
- Use a different identity for the report reader account, if you use domain accounts for your service accounts. For more information, see Service accounts and dependencies.
- Use local accounts for user accounts, if you're installing a component in a workgroup. For more information, see Service account requirements.
- Use service connections when possible. Service connections provide a secure mechanism to connect to assorted services without the need to pass in secret variables to the build directly. - Restrict these connections to the specific place they should be used and nothing more.
- Monitor service account activity and create audit streaming. Auditing allows you to detect and react to suspicious sign-ins and activity.
For more information, see Common service connection types.
Scope service connections
- Scope Azure Resource Manager, and other service connections, only to the resources and groups to which they need access. Service connections shouldn't have broad contributor rights on the entire Azure subscription.
- Don’t give users generic or broad contributor rights on the Azure subscription.
- Don’t use Azure Classic service connections, as there’s no way to scope the permissions.
- Make sure the resource group only contains Virtual Machines (VMs) or resources that the build needs access to.
- Use a purpose-specific team service account to authenticate a service connection.
For more information, see Common service connection types.
GitHub
- Disable Personal Access Token (PAT)-based authentication, so the OAuth flow gets used with the GitHub service connection.
- Never authenticate GitHub service connections as an identity that's an administrator or owner of any repositories. Check your policies.
- Never use a full-scope GitHub PAT (Personal Access Token) to authenticate GitHub service connections.
- Don't use a personal GitHub account as a service connection with Azure DevOps.
Scope permissions
The system manages permissions at different levels - individual, external, server, collection, project, object, and - and assigns them to one or more built-in groups by default.
Individual permissions
For more information, see Set individual permissions.
External guest access
- Block external guest access entirely by disabling the "Allow invitations to be sent to any domain" policy. It's a good idea to do so if there's no business need for it.
- Use a different email or user principal name (UPN) for your personal and business accounts, even though it's allowed. This action eliminates the challenge of disambiguating between your business and personal accounts when the email/UPN is the same.
- Put all the external guest users in a single Azure AD group and manage the permissions of that group appropriately. You can easily manage and audit this way.
- Remove direct assignments so the group rules apply to those users. For more information, see Add a group rule to assign access levels.
- Reevaluate rules regularly on the Group rules tab of the Users page. Clarify whether any group membership changes in Azure AD might affect your organization. Azure AD can take up to 24 hours to update dynamic group membership. Every 24 hours and anytime a group rule changes, rules get automatically reevaluated in the system.
For more information, see B2B guests in the Azure AD.
Manage security groups, policies, and settings
Security and user groups
See the following recommendations for assigning permissions to security groups and users groups.
Do | Don't |
---|---|
Use Azure Active Directory, Active Directory, or Windows security groups when you're managing lots of users. | Don’t change the default permissions for the Project Valid Users group. This group can access and view project information. |
When you're adding teams, consider what permissions you want to assign to team leads, scrum masters, and other team members who may need to create and modify area paths, iteration paths, and queries. | Don't add users to multiple security groups that contain different permission levels. In certain cases, a Deny permission level may override an Allow permission level. |
When you're adding many teams, consider creating a Team Administrators custom group where you allocate a subset of the permissions available to Project Administrators. | Don't change the default assignments made to the valid users groups. If you remove or set the View instance-level information permission to Deny for one of the Valid Users groups, no users in the group can access the project, collection, or deployment, depending on the group you set. |
Consider granting the work item query folders Contribute permission to users or groups who require the ability to create and share work item queries for the project. | Don't assign permissions that are noted as Assign only to service accounts to user accounts. |
Keep groups as small as possible. Access should be restricted, and the groups should be frequently audited. | |
Take advantage of built-in roles and default to Contributor for developers. Admins get assigned to the Project Administrator security group for elevated permissions, allowing them to configure security permissions. |
Server-level groups
See the following table of built-in security groups, which users to add, and best practice tips.
Built-in security group
Add these users
Best practice tips
Team Foundation Administrators
People who need to perform all server-level operations.
This group should be restricted to the smallest possible number of users who need total administrative control over server-level operations. If your deployment uses SharePoint or Reporting, consider adding the members of this group to the Farm Administrators and Site Collection Administrators groups in SharePoint and the Team Foundation.
Team Foundation Valid users
People who need to view server instance-level information.
This group contains all users known to exist in the server instance. You can't modify the membership of this group.
Project-level permissions
- Limit access to projects and repos to reduce the risk of leaking sensitive information and deploying insecure code to production.
- Use either the built-in security groups or custom security groups to manage permissions. For more information, see Grant or restrict permissions to select tasks.
Built-in security group
Add these users
Best practices
Project Collection Administrators
People who need total administrative control over the collection.
This group should be restricted to the smallest possible number of users who need total administrative control over the collection. For Azure DevOps, assign to administrators who customize work tracking. If your deployment uses Reporting Services, consider adding the members of this group to the Team Foundation Content Managers groups in Reporting Services
Project Collection Build Administrators
People who need to administer build resources and permissions for the collection.
Limit this group to the smallest possible number of users who need total administrative control over build servers and services for this collection.
Project-scoped users
People who need limited access to view organization settings and projects other than those projects they’re specifically added to.
Add users to this group when you want to limit their visibility and access to those projects that you explicitly add them to. Do not add users to this group if they are also added to the Project Collection Administrators group.
Removing users
- If your organization uses MSA accounts, then remove inactive users directly from the organization, as you have no other way to prevent access. When you do so, you can't create a query for work items assigned to the removed user account. For more information, see Delete users from Azure DevOps.
- If your organization is backed by Azure AD, then you can disable or delete the Azure AD user account while leaving their Azure DevOps account active. In this way, you can continue to query their work item history using their account name.
- Revoke user PATs.
- Revoke any special permissions that may have been granted to individual user accounts.
- Reassign work from users you’re removing to current team members.
Choose the right authentication method
Select your authentication methods from the following sources:
Require multi-factor authentication
Require all users to use multi-factor authentication (MFA), as a basic security feature. Multi-factor authentication requires use of more than on verification method, which adds a second layer of security to all Azure DevOps transactions.
Use Azure AD
Integrate Azure DevOps with Azure AD to have a single plane for identity. Consistency and a single authoritative source increases clarity and reduces security risks from human errors and configuration complexity. The key to end to end governance is to have multiple role assignments (with different role definitions and different resource scopes to the same Azure AD groups). Without Azure AD, you're solely responsible for controlling organization access.
For more information, see the following articles:
- About accessing your organization with Azure AD
- Add AD/Azure AD users or groups to a built-in security groups
Use PATs seldomly
Always authenticate with identity services rather than cryptographic keys when available. Managing keys securely with application code is difficult and regularly leads to mistakes like accidentally publishing sensitive access keys to code repositories like GitHub. But, if you're using PATs, see the following recommendations:
Administrators should audit all PATs using the REST APIs and revoke any PATs that don’t meet the following criteria for PATs in use:
- Should always be scoped (roles).
- Shouldn’t be global (can access more than one organization).
- Shouldn’t allow write or manage permissions on build or releases.
- Should have an expiration date.
- Should be kept secret. Your tokens are as critical as passwords.
- Should have an expiration date.
- Shouldn’t be hardcoded. It can be tempting to simplify code to get a token for a prolonged period and store it in your application, but don’t do that. They could end up in source code that could be stolen.
Keep your PATs secret. Your tokens are as critical as passwords.
Store your tokens in a safe place.
Don’t hard code tokens in applications. It can be tempting to simplify code to obtain a token for a long period of time and store it in your application, but don’t do that.
Give tokens an expiration date.
For more information, check out the following articles:
Limit access by location
Limit access to specific IP (Internet Protocol) address ranges with Azure AD Conditional Access Policy Validation. For example, you can configure a location so that MFA isn’t required for internal IP addresses.
For more information, see Using the location condition in a Conditional access policy.
Secure your network
Set up an allowlist.
Use Web application firewalls
Implement Web application firewalls (WAFs), so they can filter, monitor, and block any malicious web-based traffic to and from Azure DevOps.
- Always use encryption.
- Validate certificates.
- This shouldn’t be the only planned safety mechanism to reduce the volume and severity of security bugs in your applications.
For more information, see Application management best practices
Secure projects
- Enable the Limit user visibility for projects preview feature for the organization, which restricts access to only those projects that you add users to.
- Add users to the Project-scoped users group, so they can only see and select users and groups in the project that they're connected to from a people picker.
- Don’t allow users to create new projects. Use EasyStart “Governed Projects,” which require approval once they're submitted.
- Check out the following articles for more in-depth information about setting sub-project permissions.
Secure Azure Artifacts
Make sure you understand the difference between feeds, project, and project collection administrators. For more information, see Configure Azure Artifacts settings. For more information, see Set feed permissions.
Secure Azure Boards
- Review Configure and customize Azure Boards before you customize a process.
- See the following articles:
Secure Azure Pipelines
Use extends templates. For more information about how to set permission levels for pipelines, see Set pipeline permissions.
Policies
- Require at least one reviewer outside of the original requester. The approver takes co-ownership of the changes and should be held equally responsible for any impact it may have.
- Require CI build to pass, which is useful for establishing baseline code quality, such as code linting, unit tests, and even security checks like virus and credential scans.
- Ensure that the original pull requester can’t approve the change.
- Disallow completion of a PR (Pull Request), even if some reviewers vote to wait or reject.
- Reset code reviewer votes when recent changes get pushed.
- Lock down release pipelines by running them only on specific production branches.
- Enable “Enforce settable at queue time for variables” in your organization’s pipeline settings.
- Don’t allow “Let users override this value when running this pipeline,” for variables set in the editor.
Agents
- Grant permissions to the smallest possible number of accounts.
- Have the most restrictive firewall that leaves your agents usable.
- Update pools regularly to ensure the build fleet isn’t running vulnerable code that can be exploited by a malicious actor.
- Use a separate agent pool for build artifacts that get shipped or deployed to production.
- Segment “sensitive” pool from non-sensitive pools, and only allow the use of credentials in build definitions that are locked to that pool.
Definitions
- Manage pipeline definitions with YAML (Yet Another Markup Language). YAML is the preferred method for managing pipeline definitions, as it provides traceability for changes and can follow approval guidelines.
- Secure the pipeline definition Edit access to the minimum number of accounts.
Input
- Include sanity checks for variables in build scripts. A sanity check can mitigate a command injection attack through the settable variables.
- Set as few build variables as possible to “Settable at release time.”
Tasks
- Avoid remotely fetched resources, but, if necessary, use versioning and hash checking.
- Don’t log secrets.
- Don’t store secrets in pipeline variables, use Azure KeyVault. Regularly scan your build pipelines to ensure secrets aren’t being stored in build pipeline variables.
- Don’t let users run builds against arbitrary branches or tags on security-critical pipelines.
- Disable inheritance on the pipeline, as inherited permissions are broad and don’t accurately reflect your needs for permissions.
- Limit job authorization scopes in all cases.
Repositories and branches
- Set the “Require a minimum number of reviewers,” policy to on, so that every pull request gets reviewed by at least two approvers.
- Configure security policies specific to each repository or branch, instead of project wide. Security policies reduce risk, enforce change management standards, and improve your team’s quality of code.
- Store production secrets in a separate KeyVault and ensure that access is only granted on a need-to-know basis to keep non-production builds separate.
- Don’t mix test environments with production, including use of credentials.
- Disable forking. The more forks there are, the harder it is to keep track of each fork’s security. Also, a user can easily fork a copy of a repository to their own private account.
- Don't provide secrets to fork builds.
- Consider manually triggering fork builds.
- Use Microsoft-hosted agents for fork builds.
- For Git, check your production build definitions in the project’s git repository, so they can be scanned for credentials.
- Configure a branch control check so that only pipelines running in the context of the
production
branch may use theprod-connection
.
For more information, see Other security considerations.
For more information about granular permission controls that can be configured according to the project’s needs, see Security groups, service accounts, and permissions in Azure DevOps.
Secure Azure Repos
Improve code quality with branch policies. For more information about branch permissions and policies, see Set branch permissions.
Secure Azure Test Plans
Check out the following articles:
Secure Azure DevOps - general
- Disable inheritance where possible. Due to the allow-by-default nature of inheritance, unexpected users can get access or permissions. For more information, read about inheritance.
- Only give users and services the minimum amount of access to perform their business functions.
- Periodically review audit events to monitor and react to unexpected usage patterns by administrators and other users.
- Check out the following articles: