-
Notifications
You must be signed in to change notification settings - Fork 2
ADR for enabling CodeOps processes against Azure DevOps #41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
JamesDawson
wants to merge
1
commit into
master
Choose a base branch
from
feature/adr0002-automate-ado-mgmt
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| # Automating Azure DevOps Management Tasks via CodeOps | ||
|
|
||
| ## Status | ||
|
|
||
| Proposed | ||
|
|
||
| ## Context | ||
|
|
||
| Using a [GitOps][1] approach for managing routine configuration updates for Azure DevOps offers the possibility of: | ||
| * Devolving responsibility for such changes to those with the requirements | ||
| * Scaling-out the management overhead of making such changes | ||
| * Maintaining the required oversight via the pull request mechanism | ||
| * Strong audit trail of configuration changes | ||
|
|
||
| Here are some example scenarios: | ||
| 1. Managing access to projects | ||
| 1. Managing service connections and their security requirements | ||
|
|
||
| The premise of these [CodeOps][2] solutions relies on using a trusted Azure Active Directory (AAD) service principal to apply configuration changes instead of users running scripts from their computer or using UI tools. | ||
|
|
||
| * Users have access to the git repository and can request changes via pull request | ||
| * Administrators have approval oversight of those pull requests | ||
| * Once approved & merged an automated process runs to apply the updated configuration state from the `main` branch | ||
| * Admin access to the automated process itself is tightly controlled and the credential for the trusted identity should never be known outside of the initial registration process of the automation platform (e.g. registering the service connection with Azure DevOps) | ||
| * The repository history provides an audit trail of configuration changes | ||
|
|
||
| This approach has already been used in several scenarios, but never where the configuration being managed related to an Azure DevOps instance. | ||
|
|
||
| Currently it is not possible to grant an AAD service principal access to Azure DevOps - [documentation-reference][2]. | ||
|
|
||
| This blocks the current approach, that would otherwise use an Azure DevOps pipeline to execute the CodeOps process. | ||
|
|
||
| The remainder of this ADR outlines two approaches for resolving this issue: | ||
| * Creating a 'service account' user in AAD that the automated process uses to authenticate to Azure DevOps | ||
| * Use AAD delegation to allow an AAD application to impersonate a calling user | ||
|
|
||
| ### AAD Delegation | ||
| This fundamentally changes the approach and would necessitate a move towards the CodeOps process running as some kind of application that can be interacted with by other parties that have an AAD user context. | ||
|
|
||
| This would seem to clash with the goal of not requiring users to have the permissions needed to run the process. | ||
|
|
||
|
|
||
| ### Service Account | ||
| Whilst it would be trivial to setup a dedicated AAD user account with the required permissions to run the process, such an identity cannot always be used to natively execute a pipeline within CI/CD tools (e.g. Azure DevOps, GitHub Actions). | ||
|
|
||
| Therefore it would be necessary for the pipeline to perform a 'runas' operation when communicating with the Azure DevOps REST API. This in turn means that the credential for this user needs to be retrievable (e.g. from key vault), but this clashes with the goal to minimise the surface area for attacking the trusted identity's credential. | ||
|
|
||
| This could be mitigated by treating the password for the AAD user account as 'disposable', by allowing the automated process to generate a new password before use. For example: | ||
| * As before, the pipeline runs as a service principal (SP) | ||
| * The SP now requires additional AAD permissions, making it an 'owner' of the service account AAD user | ||
| * During the run, the pipeline enables the user and resets the password to a randomly-generated value and is only retained in-memory | ||
| * The pipeline then uses those details to authenticate to the Azure DevOps REST API | ||
| * Once completed, the SP could optionally disable the service account AAD user and/or reset the password once again | ||
|
|
||
|
|
||
| ## Decision | ||
|
|
||
| TBC | ||
|
|
||
| ## Consequences | ||
|
|
||
| ### Positive | ||
| * It is possible to perform automated processes against the Azure DevOps REST API (either directly or via other tooling e.g. azure-cli) | ||
| * No credentials need to be persisted outside of the platform running the pipeline - this includes the service principal used by the pipeline as well as the AAD service account | ||
|
|
||
| ### Negative | ||
| * Affected CodeOps processes become more complicated by needing to handle the alternative identity for the parts of their process that relate to Azure DevOps | ||
| * The AAD 'service account' user will require an Azure DevOps license - where multiple such accounts are used (e.g. to apply separation of responsibility) each one will require its own license | ||
| * The AAD service principal requires additional AAD permissions | ||
| * AAD users with permissions to manage user accounts could gain access to the service account and the permissions it has been granted | ||
| * NOTE: There is an existing equivalent attack vector for the service principal, by users with access to manage AAD applications | ||
|
|
||
|
|
||
| [1]: https://www.gitops.tech | ||
| [2]: https://endjin.com/blog/2020/11/does-your-github-repo-need-code-operations | ||
| [3]: https://docs.microsoft.com/en-us/azure/devops/integrate/get-started/authentication/authentication-guidance?view=azure-devops | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this differ from the the need to retrieve the credentials for the service principal that the pipeline operates as?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The credentials for the service principal only need to be known at the point that the service connection is registered, after that, ADO handles storing the credentials and making them available to pipeline.
Those concerns, as they relate to this additional identity, would get pushed down into the pipeline process itself (e.g. the codeops script).
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you create a generic service connection for the service account and handle it in a similar way?