# Introduction

Welcome to **SAML.to**!

SAML.to is a bridge between Identity Providers (such as GitHub OAuth) and Service Providers (such as AWS) using the SAML 2.0 Protocol.

It works by adding a configuration file to any repository of your choice called [`saml-to.yml`](/configuration/reference).

The configuration file defines Service Providers (such as AWS) and their configuration.

Also in the configuration file is lists of users that are allowed to access each Service Provider.

Using the SAML.to CLI, users can [`assume`](/usage/cli/assume) to assume roles at those services.

Here's an [Example Configuration file for our Demo Organization](https://github.com/stark-international/saml-to/blob/main/saml-to.yml), **Stark International**

## Ready to Get Started?

[Getting started is easy](https://saml.to/install). This will guide you installing our GitHub application and adding the `saml-to.yml` configuration file to your repository.

Once all set up, granting or removing access to roles is completed by editing the file.

Users granted in the `saml-to.yml` configuration file can visit <https://saml.to/apps> or by using the `saml-to assume` command to assume their granted roles.

See [Installation](/installation) for more details.

### Questions/Comments/Issues?

Please [Contact Us](https://saml.to/contact)!


# Installation

Ready to get started?

### Guided

Go to the [SAML.to Install](https://saml.to/install) page, as it will walk you through the following process:

* Installing the [SAML.to GitHub Application](https://github.com/apps/saml-to) to your GitHub User or Organization Account
* Configuring SAML.to as an Identity Provider
* Configuring Service Providers (such as AWS) and Roles for Assumption
* Creating a repository for the `saml-to.yml` configuration file
  * Automatically adds a webhook to the repository to synchronize the `saml-to.yml` configuration file with our Backend

### Manual

If you don't want to use the [Guided Installation](https://saml.to/install) page, please [Contact Us](https://saml.to/contact) for details!


# Configuration

SAML.to is a bridge between Identity Providers (such as GitHub) and Service Providers (such as AWS) using the SAML 2.0 Protocol.

By logging into an Identity Provider, a long (or short)-lived token is generated and used to identify Users and Repositories that want to exchange for a short-lived token at Service Providers.

The following pages details configuration options for[ Identity Providers](/configuration/identity-providers) and [Service Providers](/configuration/service-providers).


# Identity Providers

SAML.to has extensively verified the following Identity Providers

## Supported Identity Providers

By default, GitHub is the Identity Provider (the source of Users/Groups/Teams) that provides an OAuth functionality.

### [GitHub](#undefined)

SAML.to can exchange GitHub User or Repository tokens for:

* [AWS IAM Roles](/configuration/service-providers/aws-federated-roles)


# GitHub

## Example Configuration File

The configuration file is broken into 2 separate sections for basic functionality: `providers` and `permissions`.

```
---
# Config Reference:
# https://docs.saml.to/configuration/reference
version: '20220101'
providers:
  aws:
    entityId: https://signin.aws.amazon.com/saml
    acsUrl: https://signin.aws.amazon.com/saml
    attributes:
      https://aws.amazon.com/SAML/Attributes/RoleSessionName: '<#= user.github.login #>'
      https://aws.amazon.com/SAML/Attributes/SessionDuration: '3600'
      https://aws.amazon.com/SAML/Attributes/Role: '<#= user.selectedRole #>,<#= provider.variables.providerArn #>'
permissions:
  aws:
    roles:
      - name: arn:aws:iam::123456789012:role/cnuss-admin
        provider:
          variables:
            providerArn: arn:aws:iam::123456789012:saml-provider/saml-to
        users:
          github:
            - github-user-id-1
            - github-user-id-2
            - octokat
        repos:
          github:
            - some-repo
            - other-org/some-other-repo
```

### Providers

The `providers` section details **Service Providers** (e.g. what services can a GitHub Token be used to log in with), for example using [AWS Federated Roles](/configuration/service-providers/aws-federated-roles).

{% hint style="info" %}
The `key` in the aforementioned configuration (e.g. `aws`) **must match** between the `providers` and `permissions` sections. This is how a `permission` relates back to a particular `provider`.
{% endhint %}

It contains information like the Assertion URLs, Entity ID and other SAML attributes.

You can also use some light [Substitution Syntax](/configuration/reference/substitutions) (`<#= ... #>`) for injection of variables when a SAML Assertion (i.e. Role Assumption) is requested by a user.

See [Service Providers](/configuration/service-providers) for a detail on supported Service Providers that can be configured in the configuration file.

For more information, see the [Configuration Reference](/configuration/reference).

### Permissions

The `permissions` section details the **Access Control Lists** to various **Service Providers** and **Roles**.

The `key` of the Permission (e.g. `aws`) must be identical to the `key` of a `provider`.

For each role, you can define `github` `users:` and `repos:` in their respective sections. Defining users and repositories is optional, you can define both, or one or the other.

See [Service Providers](/configuration/service-providers) for a detail on how to configure various Service Providers, such as AWS.

For more information, see the [Configuration Reference](/configuration/reference).

#### Granting Access to Repos in Another Organization

If you use multiple organizations in GitHub that might need to use the same provider in GitHub Actions, you can simply add the specify the Organization Name.

Assuming your GitHub organization is `my-org` and you have a repository `my-repo` that needs access to the `admin` role, and you have another organization `my-other-org` with another repository `my-other-repo` that needs access to the `admin` role, the configuration would look like this:

```
permissions:
  aws:
    roles:
      - name: arn:aws:iam::123456789012:role/admin
        ...
        repos:
          github:
            - my-repo
            - my-other-org/my-other-repo
```

{% hint style="success" %}
You **do not need** to be a member or Administrator of the other Organization to make this work!
{% endhint %}


# Service Providers

{% hint style="info" %}
Do you want another system to serve as a Service Provider? Let us know by [filing an issue](https://github.com/saml-to/cli/issues/new/choose).
{% endhint %}

## Role-Based Assumption

* [AWS IAM Federated Roles](/configuration/service-providers/aws-federated-roles)
  * Exchanges an [Identity Provider](/configuration/identity-providers) token for short-lived AWS IAM Role Credentials


# AWS (Federated Roles)

SAML.to can exchange an [Identity Provider](/configuration/identity-providers) User or Repository token for short-lived AWS IAM Role Credentials.

Please see the following sections:

* [Assuming Roles](/configuration/service-providers/aws-federated-roles/assuming-roles)
* [Adding Users](/configuration/service-providers/aws-federated-roles/adding-users)
* [Adding AWS Accounts](/configuration/service-providers/aws-federated-roles/adding-aws-accounts)
* [Adding AWS Roles](/configuration/service-providers/aws-federated-roles/adding-roles)


# Assuming Roles

The SAML.to CLI has a handful ways to assume AWS roles.

## With the CLI

First, [install the `saml-to` CLI](https://github.com/saml-to/cli).

### Listing Roles

To know which roles are available to assume, use the `list-roles` subcommand.

```
saml-to list-roles
```

### Assuming Roles

### Using the Terminal to open a Browser Window

To interactively prompt for a role to assume, use the following command:

```
saml-to assume
```

Or, to assume a specific role, first [List Roles](#listing-roles), and provide the Role Name:

```
saml-to assume arn:aws:iam::123456789012:role/administrator
```

{% hint style="success" %}
Protip: You can use substring matching for role names.

\
If the Role ARN outputted from `list-roles` is `arn:aws:iam::123456789012:role/administrator`, then you can shorten it with **any unique substring** of that Role ARN.

\
For example:\
&#x20; `saml-to assume arn:aws:iam::123456789012:role/administrator`

May be shortened to:\
&#x20; `saml-to assume administrator`
{% endhint %}

### Using Environment Variables

If you add the `--headless` flag to a `saml-to assume` command, the appropriate environment variables will be added to the terminal environment:

```
$(saml-to assume administrator --headless)
```

Then, you may run AWS CLI commands, or run any process that uses the Environment Variables, such as the AWS SDK:

```
aws sts get-caller-identity
```

## In the Browser

Go to [SAML.to Apps](https://saml.to/apps) and AWS roles can be assumed by clicking on the desired "Assume" button for a listed role.


# AWS CLI

The [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) has various methods for using an AWS Token on a system, wether it be in on a Developer System, or CI/CD (such as GitHub Actions).

## Using Environment Variables

<details>

<summary>In an Interactive Terminal (e.g. Developer Laptop)</summary>

Add the `--headless` flag to the `saml-to assume` command in a subshell `$(...)`

```
$(saml-to assume the-role-name --headless)
aws sts get-caller-identity # (optional, shows the identity that is now assumed)
aws ec2 describe-instances # (or whatever AWS CLI command desired)
```

</details>

<details>

<summary>In GitHub Actions</summary>

In the Workflow YAML, use provide the Repository Secret (automatically generated using `${{ secrets.GITHUB_TOKEN }}` and the [Assume AWS Role Action](https://github.com/marketplace/actions/saml-to-assume-aws-role)

```
steps:
  - uses: saml-to/assume-aws-role-action@v1
    with:
      role: arn:aws:iam::123456789012:role/admin
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  - run: aws sts get-caller-identity # (optional, shows the identity that is now assumed)
  - run: aws ec2 describe-instances # (or whatever AWS CLI command desired)
```

</details>

## Using Profiles

<details>

<summary>In an Interactive Terminal (e.g. Developer Laptop)</summary>

Add the `--save` flag to the `saml-to assume` command

```
saml-to assume the-role-name --save
aws sts get-caller-identity --profile the-role-name
aws ec2 describe-instances --profile the-role-name
```

</details>

<details>

<summary>In GitHub Actions</summary>

Add the `profile:` option to the [Assume AWS Role Action](https://github.com/marketplace/actions/saml-to-assume-aws-role)

```
steps:
  - uses: saml-to/assume-aws-role-action@v1
    with:
      role: arn:aws:iam::123456789012:role/admin
      profile: the-profile-name
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  - run: aws sts get-caller-identity # (optional, shows the identity that is now assumed)
  - run: aws ec2 describe-instances # (or whatever AWS CLI command desired)
```

</details>

### Named Profiles

Named Profiles are useful if you need to access multiple AWS accounts or Roles in the same session

<details>

<summary>In an Interactive Terminal (e.g. Developer Laptop)</summary>

```
saml-to assume the-role-name --save role1
saml-to assume another-role-name --save role2
aws sts get-caller-identity --profile role1
aws sts get-caller-identity --profile role2
aws ec2 describe-instances --profile role1
aws ec2 describe-instances --profile role2
```

</details>

<details>

<summary>In GitHub Actions</summary>

```
steps:
  - uses: saml-to/assume-aws-role-action@v1
    with:
      role: arn:aws:iam::123456789012:role/some-role
      profile: role1
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  - uses: saml-to/assume-aws-role-action@v1
    with:
      role: arn:aws:iam::123456789012:role/another-role
      profile: role2
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  - run: aws sts get-caller-identity --profile role1
  - run: aws sts get-caller-identity --profile role2
```

</details>


# AWS SDKs

The AWS SDKs behave identically to the [AWS CLI](/configuration/service-providers/aws-federated-roles/assuming-roles/aws-cli). For example you can use [Environment Variables](/configuration/service-providers/aws-federated-roles/assuming-roles/aws-cli#using-environment-variables) or a [Named Profile](/configuration/service-providers/aws-federated-roles/assuming-roles/aws-cli#using-profiles) before the application is launced with the AWS SDK.

## Environment Variables

`myscript.py`

```
import boto3

ec2 = boto3.client('ec2')

for i in ec2.instances.all():
    if i.state['Name'] == 'stopped':
        i.start()
```

Then, to invoke `myscript.py` with temporary credentials from SAML.to, in a Subshell (`$(...)`)

```
$(saml-to assume the-role-name --headless)
python myscript.py
```

## Named Profiles

`myscript.py`

```
import boto3

ec2 = boto3.client('ec2', profile_name='the-profile-name')

for i in ec2.instances.all():
    if i.state['Name'] == 'stopped':
        i.start()
```

Then, to invoke `myscript.py` with temporary credentials from SAML.to:

```
saml-to assume the-role-name --save the-profile-name
python myscript.py
```


# Docker

Assume using a Named Profile, then Volume Link the `~/.aws` directory

```
saml-to assume the-role-name --save the-profile-name
docker run -v $(PWD)/.aws:/root/.aws amazon/aws-cli ec2 list-instances
```


# Terraform

Tokenless Terraform using SAML.to

## Introduction

The SAML.to [Command Line Interface](https://github.com/saml-to/cli) can be used for authentication to AWS and can be used with the `terraform` CLI or any tool that supports Terraform (such as `terragrunt`).

This document will detail how to use SAML.to to authenticate to AWS to run Terraform commands with Tokenless Authentication.

## Create a Terraform Runner Role

Create a `terraform-runner` role (or whatever name you prefer) that has a [Trust Relationship to SAML.to](/configuration/service-providers/aws-federated-roles/adding-roles).

<details>

<summary>Example: Role Permissions for Terraform + S3 State Storage</summary>

If the Terraform Configuration uses S3 State storage, such as:

```
terraform {
  backend "s3" {
    bucket = "mybucket"
    key    = "path/to/my/key"
    region = "us-east-1"
  }
}
```

The role needs permission to the S3 Bucket:

```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::mybucket"
    },
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
      "Resource": "arn:aws:s3:::mybucket/path/to/my/key"
    }
  ]
}
```

</details>

In `saml-to.yml`, grant access to GitHub Users to assume `terraform-runner`:

```
      - name: arn:aws::YOUR_ACCOUNT_ID:role/terraform-runner
        ...
        users:
          github:
            - SOME_GITHUB_USERNAME
            - ANOTHER_GITHUB_USERNAME
```

Ensure the role is functional:

```
$(saml-to assume terraform-runner)
aws sts get-caller-identity
```

And run `terraform init` to ensure you have access to the State File.

{% hint style="info" %}
If the Role in AWS has Read/Write permissions to the AWS account, such as `AdministratorAccess`, at this point, you can run `terraform plan` and `terraform apply` with the `terraform-runner` identity.

If you want to make a second role in the same or another account, see [A Terraform Applier Role](#optional-a-terraform-applier-role).
{% endhint %}

## Optional: A Terraform Applier Role

Create a second role in whatever AWS account you'd like, `terraform-applier` (or whatever you want to call it) that grants `terraform-runner` the ability to assume it:

<details>

<summary>Trust Relationship</summary>

```
{
  "Version": "2012-10-17",
    "Statement": [{
        "Effect": "Allow",
        "Principal": {
          "AWS": "arn:aws:iam::YOUR_ACCOUNT_ID:role/terraform-runner"
        },
        "Action": "sts:AssumeRole"
    }]
}
```

</details>

{% hint style="success" %}
It's **not necessary** to declare `terraform-applier` in the `saml-to.yml`. Role Assumption in Terraform uses STS Role Assumption internally and relies on IAM trust relationships!
{% endhint %}

Configure role assumption in Terraform:

```
terraform {
  ... uses the System Terminal Role for terraform init ...
}

provider "aws" {
  profile = "terraform-runner"
  region  = "us-east-1"
  assume_role {
    role_arn = "arn:aws:iam::THE_ACCOUNT_ID:role/terraform-applier"
  }
}

resource "aws_..." {
  ... Terraform transparently assumes terraform-applier, then creates the resource ...
}
```

Save the temporary credentials to `~/.aws/credentials` using the `--save` flag on the [SAML.to CLI](https://github.com/saml-to/cli):

```
saml-to assume terraform-runner --save
```

And run Terraform commands:

```
terraform init
terraform plan
terraform apply 
```

## Questions/Comments/Issues?

[Contact us](https://saml.to/contact)!


# Kubernetes

Tokenless Authentication to Kubernetes using SAML.to

## Introduction

The SAML.to [Command Line Interface](https://github.com/saml-to/cli) or [Assume AWS Role Action](https://github.com/saml-to/assume-aws-role-action) can be used for authentication to the Kubernetes Control Plane and be used with any tool that supports a `kubeconfig` file (such as `kubectl`, `helm`, `k9s`, etc.).

This document will detail how to use SAML.to to authenticate to the Kubernetes Control Plane for Tokenless authentication.

{% hint style="info" %}
This page is focused for AWS EKS, however if you've manually provisioned your own cluster, you'll need to first set up the [AWS IAM Authenticator](https://github.com/kubernetes-sigs/aws-iam-authenticator) on your Kubernetes cluster.
{% endhint %}

## Prerequisites

* [SAML.to has been Installed](/installation) to your GitHub Organization or User Account
* [A role (with a SAML.to Trust Relationship)](/configuration/service-providers/aws-federated-roles/adding-roles) that will be used to access Kubernetes
  * Grant yourself access in `saml-to.yml` for Testing purposes
  * At a minimum, allow the role the `eks:DescribeCluster` permission&#x20;
* A Kubernetes Cluster and the ability to run `kubectl` commands on it

## Create a Kubernetes Admin Role

Create a `kubernetes-admin` role (or whatever name you prefer) that has a [Trust Relationship to SAML.to](/configuration/service-providers/aws-federated-roles/adding-roles).

At a minimum, the role needs permission to `eks:DescribeCluster`:

```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "eks:DescribeCluster",
      "Resource": "arn:aws:eks:*:*:cluster/*"
    }
  ]
}
```

Then, in `saml-to.yml`, grant access to GitHub Users to assume that role:

```
      - name: arn:aws::YOUR_ACCOUNT_ID:role/kubernetes-admin
        ...
        users:
          github:
            - SOME_GITHUB_USERNAME
            - ANOTHER_GITHUB_USERNAME
```

Ensure the role is functional:

```
$(saml-to assume kubernetes-admin)
aws eks describe-cluster --name THE_CLUSTER_NAME [--region THE_CLUSTER_REGION]
```

## Edit the Config Map

{% hint style="warning" %}
For brevity, these instructions will detail on how to map an IAM role to the `system:masters` group for full administrative control over Kubernetes.

In Kubernetes best practices, it is not recommended to grant access to `system:masters` .

Any group configuration is supported. Refer to the Kubernetes documentation for details on creating/using Cluster Roles and Cluster Role Bindings.
{% endhint %}

If the system was provisioned by AWS EKS, you should have an `aws-auth` ConfigMap in the `kube-system` namespace:

```
kubectl edit -n kube-system configmap/aws-auth
```

Add a section to `mapRoles` allowing the desired role access to the `system:masters` group:

<pre><code><strong>    - groups:
</strong><strong>        - system:masters
</strong><strong>      rolearn: arn:aws::YOUR_ACCOUNT_ID:role/kubernetes-admin
</strong>      username: kubernetes-admin
</code></pre>

## Connect to Kubernetes Using the Role

### With The SAML.to CLI

<details>

<summary>Optional: Create or Update <code>.kubeconfig</code></summary>

Using the [SAML.to CLI](https://github.com/saml-to/cli) with the `--headless` flag will update your Terminal Session with temporary AWS Session Tokens:

```
$(saml-to assume kubernetes-admin --headless)
```

```
aws eks update-kubeconfig --name THE_CLUSTER_NAME
kbectl set-context THE_CLUSTER_ARN
```

</details>

Run `saml-to` before `kubectl` commands as you normally would:

```
$(saml-to assume kubernetes-admin --headless)
kubectl get all -A
```

Kubernetes will do the rest of the work and map the active role in the Terminal Session to a group permission level as defined in `mapRoles`!

{% hint style="info" %}
Running `$(saml-to ...)` before **every** Kubectl command is **unnecessary**.&#x20;

The credentials will stay valid in your Terminal Session for how-ever long is defined in `saml-to.yml` the property value of `https://aws.amazon.com/SAML/Attributes/SessionDuration`, which defaults to 1 hour.

If the session expires, simply run the `saml-to assume ... --headless` command again!
{% endhint %}

### Within GitHub Actions

A repository can also be granted access to the role. In your user's or organizations `saml-to.yml`, grant access for the Repository to gain access to the role:

```
      - name: arn:aws::YOUR_ACCOUNT_ID:role/kubernetes-admin
        ...
        repos:
          github:
            - name: THE_REPO_NAME
            - name: SOME_OTHER_ORG/SOME_OTHER_REPO
```

Then, in the GitHub action, use the [Assume AWS Role Action](https://github.com/saml-to/assume-aws-role-action) to assume the role:

```
      - name: Assume Role
        uses: saml-to/assume-aws-role-action@v1
        with:
          role: arn:aws::YOUR_ACCOUNT_ID:role/kubernetes-admin
          region: THE_CLUSTER_REGION
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Login to Kubernetes
        run: aws eks update-kubeconfig --name THE_CLUSTER_NAME
        
      - name: Run a Kubernetes Command
        run: kubectl apply -f some-manifest.yaml
```

## Questions/Comments/Issues?

[Contact us](https://saml.to/contact)!


# Adding Users

Adding additional users to SAML.to is easy

Any GitHub user can be added to the configuration file, they do not need to be a member of the Organization that hosts the `saml-to.yml` file.

Simply add their GitHub User handle to the `saml-to.yml` configuration file under the `users` section for the desired role:

<figure><img src="https://3725585497-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBw4oESW5uc8R6R0nkdmD%2Fuploads%2Fg8Hi195IOQtqhvpyY4g1%2FScreen%20Shot%202022-09-14%20at%205.49.43%20PM.png?alt=media&amp;token=0aad6204-29fc-44fb-baa1-6bdd76567069" alt=""><figcaption></figcaption></figure>

Removing the user from the `saml-to.yml` will immediately remove them the ability to assume the role again.


# Adding AWS Accounts

1. Add SAML.to as an Identity Provider in the desired AWS Account
   1. Navigate to [AWS Identity Providers](https://console.aws.amazon.com/iamv2/home#/identity_providers)
   2. Click **Add Provider**
      1. **Provider type**: SAML
      2. **Provider name**: saml.to
      3. **Metadata document**: [Download from SAML.to](https://saml.to/metadata)
      4. Make note of the **Provider ARN**
2. [Add a Role with a Trust Relationship](/configuration/service-providers/aws-federated-roles/adding-roles) to the new Identity Provider in AWS IAM


# Adding Roles

## Prerequisites

[Ensure SAML.to is installed](/installation) to your GitHub Organization or User Account

## Add or Update an IAM Role

<details>

<summary>Create a new role</summary>

1. Navigate to [AWS IAM Roles](https://console.aws.amazon.com/iamv2/home#/roles)
2. Click **Create Role**
   1. **Trusted entity type:** SAML 2.0 federation
   2. **SAML 2.0-based provider:** Choose the provider.
      1. If SAML.to isn't in the list, [add SAML.to to the AWS account first](/configuration/service-providers/aws-federated-roles/adding-aws-accounts).
   3. **Allow programmatic and AWS Management Console access**
   4. **Attribute:** `SAML:aud`
   5. **Value:** `https://signin.aws.amazon.com/saml`&#x20;
3. Continue the remaining steps to create the role
4. Copy the **Role ARN**<br>

</details>

<details>

<summary>Use an existing role</summary>

1. Copy the **Provider ARN** of SAML.to from [AWS IAM Providers](https://console.aws.amazon.com/iamv2/home#/identity_providers)
   1. If SAML.to isn't in the list, [add SAML.to to the AWS account first](/configuration/service-providers/aws-federated-roles/adding-aws-accounts).
2. Choose a role in [AWS IAM Roles](https://console.aws.amazon.com/iamv2/home#/roles)
3. Click the **Trust Relationships** tab
4. Click **Edit trust policy**&#x20;
5. Add a **Statement**, update the policy, and make note of the **Provider ARN**

```
{
  "Effect": "Allow",
  "Principal": {
      "Federated": "THE_PROVIDER_ARN"
  },
  "Action": "sts:AssumeRoleWithSAML",
  "Condition": {
      "StringEquals": {
          "SAML:aud": "https://signin.aws.amazon.com/saml"
      }
  }
}
```

</details>

## Update saml-to.yml

Add the following the following block to `permissions.aws.roles` to `saml-to.yml`:

```
      - name: THE-ROLE-ARN
        provider:
          variables:
            providerArn: THE-PROVIDER-ARN
        users:
          github:
            - some-github-user
            - another-github-user
        repos:
          github:
            - some-repo
            - another-org/some-other-repo
```

<figure><img src="https://3725585497-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBw4oESW5uc8R6R0nkdmD%2Fuploads%2FdNJDNZgj75uJ6hKgtNga%2FScreen%20Shot%202022-11-08%20at%207.12.08%20AM.png?alt=media&amp;token=f1c90a84-98ea-4480-abb1-cae8d9217b52" alt=""><figcaption></figcaption></figure>


# Roles for GitHub Actions

AWS Roles can be assumed in GitHub Actions by completing two steps:

1. Edit the `saml-to.yml` to include the name of the repository that needs access to a given role
   1. [Example 1](https://github.com/stark-international/saml-to/blob/9b4ea761a1e378371e2887a9ff03aa22fc3b53ec/saml-to.yml#L28): Access granted access to `some-repo` access to `stark-international-administrator`
   2. [Example 2](https://github.com/stark-international/saml-to/blob/9b4ea761a1e378371e2887a9ff03aa22fc3b53ec/saml-to.yml#L36): Access granted to `another-repo` and within `another-org`
2. Add or modify the GitHub action for the repository:
   1. [Example 1](https://github.com/stark-international/some-repo/blob/366f094e22b283f0c2baa68d0e5e53a69cccd982/.github/workflows/push-main.yml#L13-L18): A GitHub Workflow to assume `stark-international-administrator`

See [assume-aws-role-action](https://github.com/saml-to/assume-aws-role-action) for more details.


# Configuration Reference

The `saml-to.yml` configuration has a relatively simple Configuration Syntax and can easily be modified by hand.

**Generalized Structure** (and [JSON Schema](https://sso.saml.to/github/config.schema.json))

```
---
version: '20220101'
variables:
  variable1: 'VariableValue1'
  variable2: 'VariableValue2'
providers:
  provider1:
    entityId: https://provider1.com/saml
    acsUrl: https://provider1.com/saml/acs
    attributes:
      CustomAttribute1: '<#= user.github.login #>`
      CustomAttribute2: '12345'
      CustomAttribute3: 'hello my name is <#= user.github.fullName #> for <$= variable1 $>' # you can intermix subsitutions
  provider2:
    entityId: https://subdomain.provider2.com/sso
    loginUrl: https://subdomain.provider2.com
    acsUrl: https://subdomain.provider2.com/sso/acs
    nameIdFormat: 'emailV2'
    attributes:
      Email: '<#= user.github.email #>'
      FirstMame: '<#= user.github.firstName #>'
  samltest:
    entityId: https://samltest.id/saml/sp
    loginUrl: 'https://samltest.id/Shibboleth.sso/Login?entityID=<#= system.entityIdUriEncoded #>'
    nameId: '<#= user.github.firstName #>.<#= user.github.lastName #>.'@mycompany.com
    nameIdFormat: email
    acsUrl: https://samltest.id/Shibboleth.sso/SAML2/POST
    attributes: {}
permissions:
  provider1:
    roles:
      - name: Role1
        users:
          github:
            - GitHubUserName1
      - name: Role2
        users:
          github:
            - GitHubUserName1
            - JohnSmith
        repos:
          github:
            - my-repo # A repo in the same org as the `saml-to.yml`
            - some-other-org/some-other-repo # A repo in a different org
  provider2:
    users:
      github:
        - GitHubUserName1
        - JohnSmith
        - SallySue
  samltest:
    users:
      github:
        - GithubUser1
        - GithubUser2
```

## version

(Required)

Must be `20220101`.

## variables

*(Optional)*

A map of Key/Value Pairs that can be used in [`providers`](#undefined) and `permissions` keys and values.

For more information, see [Substitutions](/configuration/reference/substitutions).

## providers

(Required)

A map of Service Providers, keyed by a unique name.

* The provider key is referenced 1-1 in the [`permissions`](#undefined) object.

For each provider, the following attributes apply:

### entityId

(Required)

A URL of the Provider's Entity ID (aka Audience, Login URL)

### acsUrl

(Required)

The URL of the Providers Assertion Consumer Service URL (ACS URL)

### loginUrl

(Optional)

If SP-Initiated Logins, this is the Login URL of the Service Provider.

For IdP-Initiated Logins, leave this blank.

### nameId

(Optional)

If a custom `nameId` is required by the Service Provider, you can specify it here.

Example - Setting the email address to be first and last name at a specific domain:

```
nameId: <#= user.github.firstName #>.<#= user.github.lastName #>@mydomain.com
nameIdFormat: email
```

### nameIdFormat

(Optional)

Allowed Values: 'id', 'login', 'email', 'emailV2'

If the Provider requires a specific NameId Format, it can be defined here.

If `id`, the NameIdFormat in the SAML Response will be: `urn:oasis:names:tc:SAML:2.0:nameid-format:persistent` and be set to `user.github.id` (or the value of `nameId`, if set)

If `login`, the NameIdFormat in the SAML Response will be: `urn:oasis:names:tc:SAML:2.0:nameid-format:transient` and be set to `user.github.login` (or the value of `nameId`, if set)

If `email`, the NameIdFormat in the SAML Response will be: `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress` and be set to `user.github.email` (or the value of `nameId`, if set)

If `emailV2`, the NameIdFormat in the SAML Response will be: `urn:oasis:names:tc:SAML:2.0:nameid-format:email` and be set to `user.github.email` (or the value of `nameId`, if set)

### attributes

(Optional)

A Key/Value Map or strings as attributes to send in the SAML Request.

**Note: Ensure all values are wrapped in Quotes to ensure that they are sent to the Service Provider as strings,** unless otherwise desired by the Service Provider.

## permissions

(Required)

A map of Service Providers, keyed by provider keys defined in [`providers`](#providers).

For each provider, the following attributes apply:

### users

(Optional)

Allowed properties: `github` (which is a list of strings of GitHub Logins)

### roles

(Optional)

A list of role objects with the following properties:

#### name

(Required)

The role name at the Service Provider

#### users

(Optional)

The list of users, same structure as [`users`](#users) above.

#### repos

(Optional)

Properties: `github` (which is a list of repositories)


# Substitutions

Use Substitution Handlebars to inject Assertion-time Variables

{% hint style="info" %}
Missing something? Let us know by [filing an issue](https://github.com/saml-to/cli/issues/new/choose)!
{% endhint %}

## User Data

`<#= user.fullName #>`

`<#= user.firstName #>`

`<#= user.lastName #>`

`<#= user.email #>`

`<#= user.selectedRole #>`

`<#= user.github.id #>`

`<#= user.github.login #>`

## Repository Data

`<#= repo.fullName #>` (includes `org/`)

`<#= repo.name #>` (excludes `org/`)

`<#= repo.email #>`

`<#= repo.selectedRole #>`

## Provider Data

`<#= provider.variables.VARIABLE_NAME #>`

This is a 1-1 copy of whatever is in `provider.variables` for the role being assumed.

## System Data

`<#= system.organization #>`

`<#= system.entityId #>`

`<#= system.entityIdUriEncoded #>`

`<#= system.loginUrl #>`

`<#= system.logoutUrl #>`

`<#= system.sessionId #>`

`<#= system.selectedRole #>`


# FAQs

## What is SAML.to?

SAML.to allows GitHub Users and Repositories to assume AWS IAM Roles.

&#x20;The differences between other similar services and SAML to is:

* We do not maintain a database of users, passwords or tokens, we rely on GitHub to do so
* Relationship of Users and Roles is maintained in a Configuration File checked into a GitHub Repository
* We offer a Developer Friendly CLI and GitHub actions for assuming roles.

## Who can use SAML.to?

From individuals to enterprises. SAML.to works for anyone with one or more AWS Accounts, AWS Roles, GitHub Organizations, Teams and Users.

## Can SAML.to be used at the same time with another service (Okta, JumpCloud, AWS SSO) for role assumptions?

Yes! Trust Relationships can have **multiple statements**, meaning they can trust multiple identity providers. When adding SAML.to, [add another statement to the Trust Relationship](https://docs.saml.to/configuration/service-providers/aws-federated-roles/adding-roles#use-an-existing-role), leaving the existing statements unmodified.

<figure><img src="https://3725585497-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBw4oESW5uc8R6R0nkdmD%2Fuploads%2F7FI6oQBg7hOA1YcK620l%2FScreen%20Shot%202023-01-15%20at%202.11.36%20PM.png?alt=media&amp;token=e844bf44-9641-46e1-974e-1476ab6f9d06" alt=""><figcaption></figcaption></figure>

## How do I validate that the saml-to.yml is correct?

Check out the [Config Sync Action](https://docs.saml.to/pages/k8T42wEh5UH1NI1MMmH2#checking-saml-to.yml-for-errors).

### How is this different [OpenID Connect](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services) in GitHub Actions?

The OpenID Connect feature for GitHub is exclusively for Repositories in GitHub Actions. SAML.to does this as well, in addition to:

* Allow Users to assume the same roles on their laptop with a developer friendly CLI
* Multiple Role Assumptions in a Single Action Run

### Do I have to type the full Role ARN for a saml-to assume command?

[You can use part of the role name.](/usage/cli/assume#suffix-matching)

### How do I assume multiple roles at the same time?

[Use Named Profiles](/configuration/service-providers/aws-federated-roles/assuming-roles/aws-cli#named-profiles)

## Have another question?

[Submit an Issue on GitHub](https://github.com/saml-to/cli/issues/new/choose)

or

[Start a Discussion](https://github.com/saml-to/cli/discussions)

or

[Message us on Twitter](https://twitter.com/messages/compose?recipient_id=1475883605649940489)


# Usage

* [Using our CLI](/usage/cli)
* [Using within GitHub Actions](/usage/github-actions)


# CLI

The SAML.to CLI allows for Console-based Service Provider Login and Role Assumption.

The core commands that are used everyday are:

* [`login`](/usage/cli/login)&#x20;
* [`assume`](/usage/cli/login) (and [`list-roles`](/usage/cli/list-roles))

Visit the nested pages in this section for more detail on each command.


# login

The `login` command is the primary command to store a user token from an Identity Provider (e.g. GitHub)

If no arguments are provided, it will assume a login is requested for GitHub.

Examples:

* `saml-to login`
  * Functionally equivalent to `saml-to login github`
* `saml-to login github`
  * Begins the process for a GitHub User Token and requests a `user:email` scope&#x20;

## Usage

```
saml-to login [provider]

Login to a provider

Options:
  --help       Show help  [boolean]
  --version    Show version number  [boolean]
  --provider   The provider for which to login  [string]
  --org        Specify an organization  [string]
  --withToken  Skip Device Authentication and save the provided token to ~/.saml-to/  [string]
```

## Example Output

Following these commands, a browser window would be opened to begin the SAML Authentication flow.

```
saml-to login github

To continue, we need you to log into GitHub, and we will need the `user:email` scope to access your GitHub Identity.

Please open the browser to https://github.com/login/device and enter the code:

257C-5415


Token cached in: ~/.saml-to/github-token.json
Saved GitHub credentials to ~/.saml-to/github-token.json
```


# assume

saml-to assume

The `assume` command is the primary command that can be used to open a Web Browser to start the SAML authentication process for role assumption

If no arguments are provided, it will prompt for available roles to assume.

The `list-roles` command will also show available Service Providers for login.

Examples:

* `saml-to assume`
  * Interactively display and allow selection of a Service Provider and roles for which to assume.
  * Then opens a browser window and begins the SAML authentication process.
* `saml-to assume arn:aws:iam::874599868815:role/iam-readonly`
  * Opens a browser window and begins the SAML authentication process.
  * No interactive prompts and requires an exact match of a provider name.

#### Suffix Matching

As an added convenience, the suffix of a role can be provided instead of the full role name, if it is distinct.

For example:

**List Roles:**

```
➜  ~ saml-to list-roles
npx: installed 1 in 3.244s
┌─────────┬───────────────────────────────────────────────┬───────────┬───────────────────────┐
│ (index) │                     role                      │ provider  │          org          │
├─────────┼───────────────────────────────────────────────┼───────────┼───────────────────────┤
│    0    │    'arn:aws:iam::874599868815:role/admin'     │ 'aws-iam' │ 'stark-international' │
│    1    │ 'arn:aws:iam::874599868815:role/iam-readonly' │ 'aws-iam' │ 'stark-international' │
└─────────┴───────────────────────────────────────────────┴───────────┴───────────────────────┘
```

**These commands are all functionally equivalent:**

```
➜  ~ saml-to assume readonly
➜  ~ saml-to assume iam-readonly
➜  ~ saml-to assume role/iam-readonly
...
➜  ~ saml-to assume arn:aws:iam::874599868815:role/iam-readonly
```

#### Headless

For some providers that have a SDK that allows for Token Generation on the command line, the `saml-to` cli is also featured to output access credentials to the command line for headless interaction.

The following providers support Headless mode:

* [AWS Federated Identity](/configuration/service-providers/aws-federated-roles#headless-role-assumption) (Entity ID: `https://signin.aws.amazon.com/saml`)

To see the specific interaction with Headless mode, click the links in the aforementioned list.

## Usage

```
saml-to assume [role]

Assume a role

Options:
  --help      Show help  [boolean]
  --version   Show version number  [boolean]
  --role      The role to assume  [string]
  --org       Specify an organization  [string]
  --headless  Output access credentials to the terminal  [boolean] [default: false]
  --save      Similar to headless, but saves the CLI configuration for a provider to the config file  [string]
  --provider  Specify the provider  [string]
```

## Options

### --org

In the event you're a member of multiple organizations, with providers of the same name, you can seed the command with a specific organization with this flag.

E.g. `npx saml-to login aws --org stark-international`

### --headless

No prompts, and output vary based on the provider. See [Headless](#headless) above.

## Example Output

Following these commands, a browser window would be opened to begin the SAML Authentication flow.

```
➜  ~ npx saml-to assume
npx: installed 1 in 3.035s
? Which role would you like to assume? (Use arrow keys)
  arn:aws:iam::874599868815:role/admin [aws-iam] (stark-international)
❯ arn:aws:iam::874599868815:role/iam-readonly [aws-iam] (stark-international)
Assuming arn:aws:iam::874599868815:role/iam-readonly
➜  ~ 
```

```
➜  ~ npx saml-to assume admin
npx: installed 1 in 1.592s
Assuming admin
➜  ~ 
```

```
➜  ~ npx -q saml-to assume readonly --headless
export AWS_ACCESS_KEY_ID="ASIA...AS"
export AWS_SECRET_ACCESS_KEY="X6Vo...AU"
export AWS_SESSION_TOKEN="IQoJb...=="
```


# list-roles

saml-to list-roles

The `list-roles` command is a command to list available Service Providers that have roles that can be assumed.

## Usage

```
saml-to list-roles

Show roles that are available to assume

Options:
  --version   Show version number  [boolean]
  --help      Show help  [boolean]
  --org       Specify an organization  [string]
  --provider  Specify a provider  [string]
  --refresh   Refresh cached logins from source control  [boolean] [default: false]
```

## Options

### --org

In the event you're a member of multiple organizations, you can filter the output for a specific organization with this flag.

E.g. `npx saml-to list-roles --org stark-international`

### --provider

In the event you have a large list of providers, you can filter the output for a specific provider with this flag.

E.g. `npx saml-to list-roles --provider aws-iam`

### --refresh

SAML.to performs some caching of available logins on the backend. In the event the outputted list seems out-of-sync with what should be available, add the `--refresh` flag to the command.

The refreshed output will appear as normal, but the command might take a few extra seconds to run while the cache on the backend is refreshed.

**Note:** The `--org` flag is required for a refresh

E.g. `npx saml-to list-roles --org stark-international --refresh`

## Example Output

```
➜  ~ npx saml-to list-roles
npx: installed 1 in 3.071s
┌─────────┬───────────────────────────────────────────────┬───────────┬───────────────────────┐
│ (index) │                     role                      │ provider  │          org          │
├─────────┼───────────────────────────────────────────────┼───────────┼───────────────────────┤
│    0    │ 'arn:aws:iam::874599868815:role/iam-readonly' │ 'aws-iam' │ 'stark-international' │
└─────────┴───────────────────────────────────────────────┴───────────┴───────────────────────┘

➜  ~
```

```
➜  ~ npx saml-to list-roles --refresh --org stark-international
npx: installed 1 in 1.281s
┌─────────┬───────────────────────────────────────────────┬───────────┬───────────────────────┐
│ (index) │                     role                      │ provider  │          org          │
├─────────┼───────────────────────────────────────────────┼───────────┼───────────────────────┤
│    0    │ 'arn:aws:iam::874599868815:role/iam-readonly' │ 'aws-iam' │ 'stark-international' │
└─────────┴───────────────────────────────────────────────┴───────────┴───────────────────────┘

➜  ~
```

```
➜  ~ npx saml-to list-roles --refresh --org stark-international --provider aws-iam
npx: installed 1 in 1.242s
┌─────────┬───────────────────────────────────────────────┬───────────┬───────────────────────┐
│ (index) │                     role                      │ provider  │          org          │
├─────────┼───────────────────────────────────────────────┼───────────┼───────────────────────┤
│    0    │ 'arn:aws:iam::874599868815:role/iam-readonly' │ 'aws-iam' │ 'stark-international' │
└─────────┴───────────────────────────────────────────────┴───────────┴───────────────────────┘

➜  ~
```


# GitHub Actions

We provide the following GitHub Actions:

* [Assume AWS Role Action](/usage/github-actions/assume-aws-role-action)
* [Config Sync Action](/usage/github-actions/config-sync-action)


# Assume AWS Role Action

https\://github.com/marketplace/actions/saml-to-assume-aws-role

The Assume AWS Role action is the GitHub action that can be used in various repositories to assume a role with configured with SAML.to.

See the [Assume AWS Role Action](https://github.com/marketplace/actions/saml-to-assume-aws-role) on GitHub for more information!

Assuming you have already [Installed SAML.to](/installation), the Assume AWS Role Action can be used in GitHub Actions. For example:

```
   jobs:
     prerelease:
       runs-on: ubuntu-latest
       steps:
         - uses: saml-to/assume-aws-role-action@v1
           env:
             GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
           with:
             role: "THE_DESIRED_ROLE_ARN"
         - run: aws ec2 describe-instances
```


# Config Sync Action

https\://github.com/marketplace/actions/saml-to-config-sync

The SAML.to Config Sync action is an alternative and/or supplement to the webhook that is installed on the `saml-to` repository.

Upon invocation, it will request the SAML.to backend to refresh any changes made to the `saml-to.yml` configuration file.

```
steps:
  - uses: saml-to/config-sync-action@v1
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

This will inform the SAML.to backend to refresh the `saml-to.yml` file on the **default branch** of the repository.

### Checking saml-to.yml for errors

The `saml-to.yml` file can be edited directly or using Pull Requests (PRs), but if you would like to check the `saml-to.yml` for errors during a PR, it has a `dryrun` mode so checks for correctness can be made:

```
name: Validate
on:
  workflow_dispatch:
  push:
    branches:
      - "*"
  pull_request:
    branches:
      - main
      
jobs:
  validate-saml-to:
    runs-on: ubuntu-latest
    steps:
      - uses: saml-to/config-sync-action@v1
        with:
          dryrun: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```


# Advanced Usage


# AWS


# CloudWatch Dashboard Sharing

## Initial Setup

1. [Set up SSO for CloudWatch dashboard sharing](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-dashboard-sharing.html#share-cloudwatch-dashboards-setup-SSO)
   1. When setting **Identity Providers** on the **Cognito User Pool**, choose **SAML**
   2. When prompted for a **Metadata document**
      1. Upload the [IdP Metadata from SAML.to](https://saml.to/metadata) for your User or Organization
   3. When prompted for the **Provider name**
      1. Input `saml-to`
2. In [Dashboard Sharing](https://us-east-1.console.aws.amazon.com/cloudwatch/home?region=us-east-1#settings:/dashboardSharing), select `saml-to` as the Identity Provider
3. Go to the desired Dashboard in CloudWatch
   1. Click **Actions** then **Share Dashboard**&#x20;
   2. Under **Share all your account’s CloudWatch dashboards using single sign-on (SSO)**
      1. Under **Resources**
         1. <mark style="color:green;">Make note of the</mark> <mark style="color:green;"></mark><mark style="color:green;">**Sharable Link**</mark> (e.g. `https://cloudwatch.amazonaws.com/dashboard.html?...`)
         2. Navigate to the **Cognito UserPoolIdentityProvider**&#x20;
            1. <mark style="color:green;">Make note of the</mark> <mark style="color:green;"></mark><mark style="color:green;">**User Pool ID**</mark> (e.g. `us-east-1_Q046sC47y`)
            2. <mark style="color:green;">Under Make note of the</mark> <mark style="color:green;"></mark><mark style="color:green;">**Cognito Domain**</mark> (e.g. `https://cw-db-580360238192.auth.us-east-1.amazoncognito.com`)
4. Edit `saml-to.yml` in your configured repository and make the following changes:

```
providers:
  ...
  my-dashboard:
    loginUrl: 'YOUR_DASHBOARD_SHAREABLE_LINK'
    entityId: 'urn:amazon:cognito:sp:YOUR_USER_POOL_ID'
    acsUrl: 'YOUR_COGNITO_DOMAIN/saml2/idpresponse'
    nameIdFormat: email
  ...
permissions:
  ...
  my-dashboard:
    users:
      github:
        - YOUR_GITHUB_USER_ID
        - ANOTHER_GITHUB_USER_ID
```

* Replace `YOUR_DASHBOARD_SHAREABLE_LINK` with the **Shareable Link** above
* Replace `YOUR_USER_POOL_ID` with the **User Pool ID** above
* Replace `YOUR_COGNITO_DOMAIN` with the **Cognito Domain** above
* Replace `YOUR_GITHUB_USER_ID` with your GitHub Login
  * Add other GitHub users as-needed!

## Opening the Dashboard

After installing the [SAML.to CLI](https://github.com/saml-to/cli), run the following command:

```
saml-to login my-dashboard
```

Which will open a browser window to the dashboard!


