Skip to content

Workload Identity: JWT SVID OIDC compatability#47079

Merged
strideynet merged 5 commits intomasterfrom
strideynet/oidc-compatability-jwt-svids
Oct 8, 2024
Merged

Workload Identity: JWT SVID OIDC compatability#47079
strideynet merged 5 commits intomasterfrom
strideynet/oidc-compatability-jwt-svids

Conversation

@strideynet
Copy link
Copy Markdown
Contributor

@strideynet strideynet commented Oct 2, 2024

Closes #46279

Example JWT contents demonstrating inclusion of iss claim.

{
  "alg": "RS256",
  "kid": "hSJIoAKLz5YKM07IUsk9tkhJxKaCBGRI6L1ElNFHyMM",
  "typ": "JWT"
}
{
  "aud": "example.com",
  "exp": 1727873499,
  "iat": 1727873199,
  "iss": "https://leaf.tele.ottr.sh/workload-identity",
  "jti": "e5b249c5e25e8a6f63d1889a9366f813",
  "sub": "spiffe://leaf.tele.ottr.sh/example-2"
}

Checked against:

  • GCP
  • AWS
  • Azure

GCP

https://cloud.google.com/iam/docs/workload-identity-federation-with-other-providers

terraform {
  required_providers {
    google = {
      source = "hashicorp/google"
      version = "4.51.0"
    }
  }
}

provider "google" {
  project = "teleport-dev-320620"
}

data "google_project" "project" {
}

// Create core IAM resources necessary for Workload Identity issued by Teleport
// to be used to authenticate to GCP resources.
resource "google_iam_workload_identity_pool" "leaf_cluster" {
  workload_identity_pool_id = "noah-leaf-cluster"
}

resource "google_iam_workload_identity_pool_provider" "workload_identity_oidc" {
  workload_identity_pool_id          = google_iam_workload_identity_pool.leaf_cluster.workload_identity_pool_id
  workload_identity_pool_provider_id = "workload-id-oidc"
  attribute_mapping                  = {
    "google.subject" = "assertion.sub"
  }
  oidc {
    issuer_uri        = "https://leaf.tele.ottr.sh/workload-identity"
  }
}

// Create a sample bucket and grant access to our "example" SPIFFE ID
resource "google_storage_bucket" "demo" {
  name          = "noah-workload-id-demo"
  location      = "EU"
  force_destroy = true

  uniform_bucket_level_access = true
}

resource "google_storage_bucket_iam_binding" "binding" {
  bucket = google_storage_bucket.demo.name
  role = "roles/storage.admin"
  members = [
    "principal://iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.leaf_cluster.workload_identity_pool_id}/subject/spiffe://leaf.tele.ottr.sh/example",
  ]
}
➜  teleport git:(strideynet/combined) ✗ cat /Users/noah/Downloads/clientLibraryConfig-workload-id-oidc.json
{
  "universe_domain": "googleapis.com",
  "type": "external_account",
  "audience": "//iam.googleapis.com/projects/737243897559/locations/global/workloadIdentityPools/noah-leaf-cluster/providers/workload-id-oidc",
  "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
  "token_url": "https://sts.googleapis.com/v1/token",
  "credential_source": {
    "file": "/Users/noah/gcp-workload-id-jwt",
    "format": {
      "type": "text"
    }
  }
}
➜  teleport git:(strideynet/combined) ✗ gcloud auth login --cred-file /Users/noah/Downloads/clientLibraryConfig-workload-id-oidc.json                           

Authenticated with external account credentials for: [principal://iam.googleapis.com/projects/737243897559/locations/global/workloadIdentityPools/noah-leaf-cluster/subject/spiffe://leaf.tele.ottr.sh/example].
Your current project is [teleport-dev-320620].  You can change this setting by running:
  $ gcloud config set project PROJECT_ID
➜  teleport git:(strideynet/combined) ✗ gcloud storage cp  ./hello-world gs://noah-workload-id-demo       
Copying file://./hello-world to gs://noah-workload-id-demo/hello-world
  Completed files 1/1 | 15.0B/15.0B                                                                                                                                                                                                                                                                               
➜  teleport git:(strideynet/combined) ✗ gcloud storage ls gs://noah-workload-id-demo       
gs://noah-workload-id-demo/hello-world

AWS

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "us-west-2"
  profile = "teleport-dev-sso-noah"
}

resource "aws_iam_openid_connect_provider" "leaf_tele_ottr_sh_workload_identity" {
  url = "https://leaf.tele.ottr.sh/workload-identity"

  client_id_list = [
    "sts.amazonaws.com",
  ]

  thumbprint_list = [
    "5f28d9c589ee4bf31a11b78c72b8d13f079ddc45"
  ]
}

// Create a role that the workload identity will assume with the policy below
// attached.
resource "aws_iam_role" "workload_id_demo" {
  name = "noah-workload-id-demo"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Principal = {
          Federated = aws_iam_openid_connect_provider.leaf_tele_ottr_sh_workload_identity.arn
        }
        Action = "sts:AssumeRoleWithWebIdentity"
        Condition = {
          StringEquals = {
            "${aws_iam_openid_connect_provider.leaf_tele_ottr_sh_workload_identity.url}:aud" = "sts.amazonaws.com"
            "${aws_iam_openid_connect_provider.leaf_tele_ottr_sh_workload_identity.url}:sub" = "spiffe://leaf.tele.ottr.sh/example"
          }
        }
      }

    ]
  })
}


// Create bucket and policy that grants access to it
resource "aws_s3_bucket" "workload_id_demo" {
  bucket = "noah-workload-id-demo"
}

resource "aws_iam_policy" "workload_id_demo_bucket_full_access" {
  name        = "noah-workload-id-demo-bucket-full-access"
  path        = "/"
  description = "My test policy"


  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "s3:*"
        Effect = "Allow"
        Resource = [
          aws_s3_bucket.workload_id_demo.arn,
          "${aws_s3_bucket.workload_id_demo.arn}/*"
        ]
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "workload_id_demo__workload_id_demo_bucket_full_access" {
  role       = aws_iam_role.workload_id_demo.name
  policy_arn = aws_iam_policy.workload_id_demo_bucket_full_access.arn
}
➜  aws AWS_ROLE_ARN=arn:aws:iam::278576220453:role/noah-workload-id-demo AWS_WEB_IDENTITY_TOKEN_FILE=~/aws-workload-id-jwt aws s3 cp ../../../teleport/hello-world s3://noah-workload-id-demo
upload: ../../../teleport/hello-world to s3://noah-workload-id-demo/hello-world
➜  aws AWS_ROLE_ARN=arn:aws:iam::278576220453:role/noah-workload-id-demo AWS_WEB_IDENTITY_TOKEN_FILE=~/aws-workload-id-jwt aws s3 ls s3://noah-workload-id-demo
2024-10-03 13:49:38         15 hello-world

changelog: Teleport Workload ID issued JWT SVIDs are now compatible with OIDC federation with a number of platforms.

@strideynet strideynet marked this pull request as ready for review October 3, 2024 13:21
@strideynet strideynet requested a review from timothyb89 October 4, 2024 08:58
@public-teleport-github-review-bot public-teleport-github-review-bot Bot removed the request for review from fspmarshall October 7, 2024 18:34
@strideynet strideynet added this pull request to the merge queue Oct 8, 2024
Merged via the queue into master with commit b266c28 Oct 8, 2024
@strideynet strideynet deleted the strideynet/oidc-compatability-jwt-svids branch October 8, 2024 07:44
@public-teleport-github-review-bot
Copy link
Copy Markdown

@strideynet See the table below for backport results.

Branch Result
branch/v16 Failed

strideynet added a commit that referenced this pull request Oct 8, 2024
* Start working on OIDC compatability of JWT SVIds

* Refactor existing oidc helpers

* Add tests for endpoints

* omitempty

* Add field required by AWS
github-merge-queue Bot pushed a commit that referenced this pull request Oct 8, 2024
* Workload Identity: JWT SVID OIDC compatability (#47079)

* Start working on OIDC compatability of JWT SVIds

* Refactor existing oidc helpers

* Add tests for endpoints

* omitempty

* Add field required by AWS

* Correct test algs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Workload ID: SPIFFE JWT OIDC IDToken Compatability

3 participants