> ## Documentation Index
> Fetch the complete documentation index at: https://anaconda.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Programmatic access with machine users

export const Comments = ({children}) => {
  return <div class="my-4 px-5 py-4 overflow-hidden rounded-2xl flex gap-3 border border-zinc-500/20 bg-zinc-50/50 dark:border-zinc-500/30 dark:bg-zinc-500/10" data-callout-type="comments">
      <div class="w-4">
        <svg width="14" height="14" viewBox="0 0 640 640" fill="currentColor" xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" aria-label="Comments">
            <path d="M320 112C434.9 112 528 205.1 528 320C528 434.9 434.9 528 320 528C205.1 528 112 434.9 112 320C112 205.1 205.1 112 320 112zM320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM280 400C266.7 400 256 410.7 256 424C256 437.3 266.7 448 280 448L360 448C373.3 448 384 437.3 384 424C384 410.7 373.3 400 360 400L352 400L352 312C352 298.7 341.3 288 328 288L280 288C266.7 288 256 298.7 256 312C256 325.3 266.7 336 280 336L304 336L304 400L280 400zM320 256C337.7 256 352 241.7 352 224C352 206.3 337.7 192 320 192C302.3 192 288 206.3 288 224C288 241.7 302.3 256 320 256z" />
        </svg>
      </div>
      <div class="text-sm prose min-w-0 w-full">
        {children}
      </div>
    </div>;
};

All access to Anaconda Platform is centrally authenticated and authorized. Human users authenticate through your SSO system. External systems that do not correspond to a human user, such as a [CI/CD pipeline](/docs/platform/guides/deploy/cicd-integration), authenticate as *machine users*.

A machine user is a service account: a platform managed identity that authenticates with credentials issued by an external provider, such as GitHub Actions, CircleCI, GitLab, or AWS IAM, instead of a person's SSO login.

Like human users, machine users receive per-perimeter privileges, so you control exactly what each automated system can do.

For more information, see [What is a user?](/docs/platform/concepts/what-is-a-user) and [Roles and privileges](/docs/platform/concepts/roles-and-privileges).

<Badge shape="pill" stroke color="blue">Admin only</Badge>

## Creating a machine user

1. Select **Users** in the left-hand navigation, then select the **Machines** tab.
2. Click **Create New**.
3. Select the machine user type that matches the system you are connecting, then enter a **Name** and **Description**.
4. Enter the claim values for the selected type, as described in the sections below.
5. Click **Submit**.

After you create the machine user, click it in the list to view a generated sample configuration for that type, such as a GitHub Actions workflow or a CircleCI config, that shows how to authenticate as the machine user and trigger flows.

## Choosing an identity provider

For OIDC-based types, the **Attributes to validate** section of the form lists the claims from the provider's OIDC token that the platform validates during authentication. A machine user can only be used by jobs whose token claims match the values you enter. The available claims depend on the system you are connecting. Select your provider for details:

<Tabs>
  <Tab title="GitHub Actions">
    GitHub Actions jobs authenticate as machine users with OIDC tokens (JWTs) issued by GitHub. A job requests a token and uses it to authenticate to the platform to run, deploy, and trigger flows.

    The form asks for the claims that appear in GitHub's OIDC token:

    * **Organization**: The GitHub organization that owns the repository.
    * **Repository**: The repository that runs the jobs.
    * **Branch**: Optional. If set, only jobs triggered from this branch can use the machine user.
    * **Environment**: Optional. If set, only jobs running within this environment can use the machine user.
    * **Workflow**: Optional. If set, only jobs running with this workflow name can use the machine user.

    The generated sample workflow shown after creation includes the token request and authentication commands.
  </Tab>

  <Tab title="CircleCI">
    CircleCI jobs authenticate as machine users with OIDC tokens (JWTs) issued by CircleCI. CircleCI exposes these tokens to jobs as the `$CIRCLE_OIDC_TOKEN` and `$CIRCLE_OIDC_TOKEN_V2` environment variables, and either token can authenticate to the platform.

    The form asks for the claims that appear in CircleCI's OIDC token:

    * **Organization ID**: The UUID of the CircleCI organization. Find it on the Overview page of Organization Settings in CircleCI.
    * **Project ID**: The UUID of the CircleCI project. Find it on the Overview page of Project Settings in CircleCI.
    * **Source Control Repository**: The URL of the source control repository without the protocol, such as `github.com/<ORGANIZATION>/<REPOSITORY>`.
    * **Branch**: Optional. If set, only jobs triggered from this branch can use the machine user.
  </Tab>

  <Tab title="GitLab">
    GitLab CI/CD jobs authenticate as machine users with OIDC tokens (JWTs) issued by GitLab through the [`id_tokens` keyword](https://docs.gitlab.com/ci/secrets/id_token_authentication/). GitLab exposes the token to your pipeline as a CI variable, which the pipeline uses to authenticate to the platform.

    The form asks for the claims that appear in GitLab's OIDC token:

    * **Project ID**: The GitLab project's identification number. Find it in General Settings in your repository on GitLab.
    * **Project Name**: The name of the GitLab project. For `https://gitlab.com/<NAMESPACE>/my-project`, the project name is `my-project`.
    * **Project Namespace Path**: The namespace path of the GitLab project. For `https://gitlab.com/<NAMESPACE>/my-project`, the namespace path is `<NAMESPACE>`.
    * **Branch**: Optional. The branch from which GitLab jobs authenticate as this machine user.
    * **Environment**: Optional. The environment from which GitLab jobs authenticate as this machine user.
    * **Pipeline Source**: Optional. The source type that triggered the pipeline, such as `push`.
    * **GitLab JWKS URL**: Set this if you host your own GitLab instance. The form pre-fills `https://gitlab.com/oauth/discovery/keys` for gitlab.com.

    <Warning>
      **The `aud` value is not set automatically.**

      GitLab evaluates `id_tokens` when the pipeline is created, before any scripts run. Set the `aud:` value in your `.gitlab-ci.yml` to your Anaconda Platform URL. The value cannot be templated from `obproject.toml`. For the YAML pattern, see [CI/CD integration](/docs/platform/guides/deploy/cicd-integration).
    </Warning>
  </Tab>

  <Tab title="AWS IAM">
    Systems that can assume an AWS IAM role authenticate as machine users through that role. Most CI/CD systems, microservices, and cloud environments have established, secure ways to provide AWS credentials, so the platform can rely on the same mechanism to authenticate machine users.

    Enter the role's ARN in the **IAM Role ARN** field. The platform links the role ARN to the machine user for authentication.

    ### Preparing the role

    The role needs a permission policy that lets it read the platform's authentication secrets. The policy references the platform's control plane account ID, which Anaconda provides. If the role resides in a different AWS account than your deployment, Anaconda must also register that account. Contact [Anaconda support](https://support.anaconda.com/) to get the control plane account ID and register your account. Registering an account is a one-time operation; machine users you add later in the same account do not need further registration.

    To prepare the role:

    1. In the AWS Console, create or choose an IAM role in the account where your external system runs.

    2. Navigate to IAM, then Policies, and click **Create policy**.

    3. In the policy editor, select the JSON view and add the following statements:

       ```json theme={null}
       {
           "Effect": "Allow",
           "Action": "secretsmanager:GetSecretValue",
           "Resource": "arn:aws:secretsmanager:<REGION>:<CONTROL_PLANE_ACCOUNT_ID>:secret:*"
       },
       {
           "Effect": "Allow",
           "Action": "kms:Decrypt",
           "Resource": "arn:aws:kms:<REGION>:<CONTROL_PLANE_ACCOUNT_ID>:key/*"
       }
       ```

           <Comments>
             Replace \<REGION> with the AWS region where your deployment runs.<br />
             Replace \<CONTROL\_PLANE\_ACCOUNT\_ID> with the AWS account ID provided by Anaconda. This is not the same as the account where your deployment runs.
           </Comments>

    4. Name the policy and create it, then attach it to the role from the role's **Add permissions** menu.

    The role is now ready to use with machine users.
  </Tab>

  <Tab title="Static API Key">
    Static API keys authenticate external systems without an OIDC provider. Instead of validating token claims, the platform issues the machine user one or more static tokens to present directly.

    Under **API Keys**, enter a name in the **Create a key** field and click **Generate**. Key names must start with a letter and can contain only letters, numbers, hyphens, and underscores.

    <Warning>
      Copy the key immediately. The platform shows the key value only once at creation.
    </Warning>
  </Tab>

  <Tab title="Azure DevOps">
    Azure DevOps Pipelines authenticate as machine users with OIDC tokens issued through [Microsoft Entra workload identity federation](https://learn.microsoft.com/en-us/azure/devops/pipelines/release/configure-workload-identity). The pipeline's `AzureCLI@2` task obtains the token when `addSpnToEnvironment: true` is set against a configured Azure service connection, and passes it to `outerbounds service-principal-configure` with `--jwt-token`.

    The auth chain involves two objects you set up together:

    * An **Azure DevOps service connection** in your Azure DevOps project, federated to a Microsoft Entra app registration. Set this up in your Azure DevOps Project Settings under Service Connections.
    * An **Azure DevOps machine user** on the platform. When you create the machine user, the form lists the claim fields the OIDC token carries, such as the Microsoft Entra tenant ID, the app (client) ID, the Azure DevOps organization URL, and the project name.

    The platform validates the Microsoft Entra claims when the pipeline attempts to authenticate. The service connection on the Azure DevOps side makes those claims available to the pipeline in the first place.

    For the corresponding YAML pattern, see [Using Anaconda Platform with Azure DevOps](/docs/platform/guides/deploy/cicd-integration#using-anaconda-platform-with-azure-devops).
  </Tab>
</Tabs>

## Using a machine user

After you create a machine user, open it from the list on the **Machines** tab and select a machine user from the list. The page shows an example configuration specific to that machine user, such as a GitHub Actions workflow or a GitLab CI configuration, that you can copy into your repository and adapt to your use case.

The example handles installation and configuration of the `outerbounds` package for the CI/CD workflow environment, authenticating as the machine user with the credential for its type. For example, GitHub Actions machine users authenticate with GitHub's OIDC token, and GitLab machine users authenticate with GitLab's OIDC token.

Once configured, the CI/CD environment can run Metaflow flows, access artifacts, and deploy workflows programmatically as the machine user, within the privileges you granted.
