Skip to content
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

Add support for OIDC during prebuild #63

Merged
merged 18 commits into from
Jun 21, 2024
Merged

Conversation

markphip
Copy link
Contributor

@markphip markphip commented Jun 20, 2024

Secret-less Azure DevOps Prebuilds

It is possible to avoid using PATs entirely and dynamically obtain a token during prebuild using
OIDC. This requires creating a Managed Identity or App Registration in Entra, and creating a
Federated Identity Credential on the Service Principal for the branch you are prebuilding. The
Service Principal created must also be added to Azure DevOps and given permission to the repositories
and feeds you will be accessing during the prebuild process. The configuration replaces the cloneSecret
with parameters for the Azure clientID and tenantID and also requires adding the feature for
the azure-cli:

{
"image": "mcr.microsoft.com/devcontainers/universal:ubuntu",
"features": {
    "ghcr.io/devcontainers/features/azure-cli:1": {},
    "ghcr.io/microsoft/codespace-features/external-repository:latest": {
        "cloneUrl": "https://dev.azure.com/contoso/_git/reposname",
        "clientID": "xxxx-yyyy-zzzz",
        "tenantID": "1111-2222-3333",
        "folder": "/workspaces/ado-repos"
    }
},
"workspaceFolder": "/workspaces/ado-repos",
"initializeCommand": "mkdir -p ${localWorkspaceFolder}/../ado-repos",
"onCreateCommand": "external-git clone",
"postStartCommand": "external-git config"     
}

In this scenario, during the prebuild process an ADO token will be obtained via OIDC and the Federated Identity Credential.
This token will be used during the git clone process only. If you have other scripts you are running during
onCreateCommand you can run the command external-git prebuild and the ADO token will be sent to stdout for you
to use in your scripts to install dependencies from feeds or anything else you may need. The token will only be
available during the prebuild process and this has to be done after the clone command so that the OIDC login has
already happened.

Note

You MUST install the Azure CLI feature in your devcontainer.json if using this option

Copy link
Contributor

@dmichon-msft dmichon-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For clarity, the token will get fetched and stored in the environment variable when the external-git clone command executes?

src/external-repository/scripts/clone.sh Outdated Show resolved Hide resolved
@markphip
Copy link
Contributor Author

I need to do some manual testing soon, but the expectation I have is that the code will create an environment variable with the name provided in cloneSecret and this will be populated by the clone command and should still be around for anything that comes after that needs to use it. Such as installing npm packages.

Thanks for the fixes. I let Copilot Workspace write some of the code and still need to look at it more closely obviously

@markphip
Copy link
Contributor Author

@dmichon-msft I did some research and I do not believe the environment variable will still be set when the clone command ends. I think it would be good if there were a way for it to be usable in the rest of the onCreateCommand processing. Open to ideas

@dmichon-msft
Copy link
Contributor

@dmichon-msft I did some research and I do not believe the environment variable will still be set when the clone command ends. I think it would be good if there were a way for it to be usable in the rest of the onCreateCommand processing. Open to ideas

A couple of ideas:

  1. Make a separate CLI command that gets the access token and writes it to stdout (i.e. just abstract away the OIDC interaction from the caller). This command can then just be used to populate an environment variable and pass it into the existing external-git clone command.
  2. Since Azure CLI persists login state if you don't explicitly clear it, currently the caller could get a new token with just another call to az account get-access-token to use for package feed.

@markphip
Copy link
Contributor Author

So the second option sounds pretty doable. I think we can start with that and as a couple of teams use this we can see if there is something to make it easier.

Aside from just being the correct place to get the token
this also allows a user to run this command after clone to get a
token on stdout
@markphip
Copy link
Contributor Author

@dmichon-msft I think I have it now. I was adding the token code in the wrong place anyway. So it is now in a command external-git prebuild that you can run in your scripts and it will echo the token to stdout. This command was already being used as the git credential helper during clone so I moved everything into that and cleaned things up.

@markphip
Copy link
Contributor Author

I was able to test and verify this all works now. Just doing some final testing of a few error scenarios to make sure they can be diagnosed then will merge and publish

@markphip markphip merged commit c6f5ab7 into main Jun 21, 2024
6 checks passed
@markphip markphip deleted the markphip/add-oidc-support branch June 21, 2024 15:37
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.

2 participants