+++
date = "2026-02-06"
title = "AWS STS: Validate OIDC provider claims from GitHub, Google, CircleCI, and OCI"
slug = "aws-sts-oidc-claim-validation"
tags = [
    "aws",
    "sts",
    "iam",
    "oidc",
    "security",
    "github-actions",
    "circleci",
    "google",
    "oci",
]
categories = [
    "aws",
]
series = ["AWS"]
+++

AWS ได้ประกาศอัปเดตสำหรับ AWS Security Token Service (STS): ตอนนี้คุณสามารถตรวจสอบ JWT claims เฉพาะของผู้ให้บริการข้อมูลประจำตัวที่เลือกได้จาก **Google**, **GitHub**, **CircleCI**, และ **Oracle Cloud Infrastructure (OCI)** เมื่อคุณใช้ `AssumeRoleWithWebIdentity` สิ่งนี้สำคัญเพราะทำให้การเขียน **นโยบายความน่าเชื่อถือของ IAM ที่เข้มงวด** สำหรับ OIDC-based federation (CI/CD, workload identity) ง่ายขึ้น โดยไม่ต้องพึ่งพารูปแบบที่กว้างเกินไป

ที่มา: [AWS announcement](https://aws.amazon.com/about-aws/whats-new/2026/01/aws-sts-supports-validation-identity-provider-claims/)

## ทำไมสิ่งนี้ถึงมีประโยชน์

หากคุณใช้ OIDC federation อยู่แล้ว คุณอาจเคยทำอย่างน้อยหนึ่งในสิ่งเหล่านี้:

- จำกัดการเข้าถึงด้วยรูปแบบ `sub` เดียว และหวังว่ามันจะเฉพาะเจาะจงเพียงพอ
- ใช้ชื่อ repository หรือชื่อ branch ที่เปลี่ยนได้ง่าย
- ยอมรับ "เวิร์กโฟลว์ใดๆ ในองค์กรนี้สามารถ assume role ได้" เพราะนโยบายซับซ้อนเกินไป

คีย์ claim เฉพาะของผู้ให้บริการช่วยให้คุณแสดงเจตนาได้ชัดเจนยิ่งขึ้น: "เฉพาะ repo นี้ (ตาม ID ที่ไม่เปลี่ยนรูป)", "เฉพาะ enterprise นี้", "เฉพาะเวิร์กโฟลว์นี้", "เฉพาะ actor นี้"

## ตัวอย่าง: เงื่อนไขนโยบายความน่าเชื่อถือของ GitHub Actions

สำหรับ GitHub Actions, AWS รองรับคีย์เงื่อนไขที่แมปกับ OIDC claims ทั่วไปของ GitHub

| **AWS STS condition key** | **IdP JWT claim** | **Available in session** |
| -- | -- | -- |
| actor | actor | No |
| actor_id | actor_id | No |
| job_workflow_ref | job_workflow_ref | No |
| repository | repository | No |
| repository_id | repository_id | No |
| workflow | workflow | No |
| ref | ref | No |
| environment | environment | No |
| enterprise_id | enterprise_id | No |

หมายเหตุเกี่ยวกับ "available in session": การตรวจสอบ claim เหล่านี้จะถูกประเมินในขั้นตอน **role assumption** (trust policy) พวกมันไม่ได้ถูกสร้างขึ้นโดยอัตโนมัติเป็น attributes ที่คุณสามารถอ้างอิงได้ในภายหลังภายในนโยบายสิทธิ์ของ role

### รูปแบบการใช้งานจริง

- `token.actions.githubusercontent.com:actor`: ระบุ *ใคร* เป็นผู้เรียกใช้เวิร์กโฟลว์ ตัวอย่างเช่น หาก actor คือ `dependabot[bot]` คุณอาจอนุญาตให้เข้าถึงแบบอ่านอย่างเดียวเท่านั้น
- `token.actions.githubusercontent.com:repository_id`: ควรใช้ ID ที่ไม่เปลี่ยนรูปแทนชื่อ เพื่อหลีกเลี่ยงสถานการณ์ "เปลี่ยนชื่อเพื่อเลี่ยงนโยบาย"
- `token.actions.githubusercontent.com:enterprise_id`: ตรวจสอบให้แน่ใจว่าเฉพาะเวิร์กโฟลว์จาก GitHub Enterprise ของคุณเท่านั้นที่สามารถ assume role ได้

### ตัวอย่างนโยบายความน่าเชื่อถือของ IAM (GitHub Actions)

นี่คือรูปแบบนโยบายที่ฉันชอบ: รักษานโยบายความน่าเชื่อถือให้เข้มงวด และจำกัดสิทธิ์ให้อยู่ในขอบเขตการดำเนินการที่จำเป็นขั้นต่ำ

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com" },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
          "token.actions.githubusercontent.com:repository_id": "123456789",
          "token.actions.githubusercontent.com:enterprise_id": "987654321"
        },
        "StringLike": {
          "token.actions.githubusercontent.com:ref": "refs/heads/main",
          "token.actions.githubusercontent.com:job_workflow_ref": "my-org/my-repo/.github/workflows/deploy.yml@refs/heads/main"
        }
      }
    }
  ]
}

คำแนะนำสั้นๆ ลิงก์ไปยังหัวข้อ

  • ควรใช้ ตัวระบุที่ไม่เปลี่ยนรูป (repository_id, enterprise_id) แทนชื่อเท่าที่จะทำได้
  • ถือว่านโยบายความน่าเชื่อถือเป็น “การควบคุมการเข้าถึง” ของคุณ: ทำให้มันแคบที่สุดเท่าที่จะทำได้
  • อย่าพึ่งพา OIDC federation session เพื่อ “ส่ง” claims เหล่านี้ หากคุณต้องการบริบทการตรวจสอบที่สมบูรณ์ยิ่งขึ้น ให้วางแผนอย่างชัดเจน (CloudTrail, การบันทึกเพิ่มเติม หรือ roles แยกต่างหากสำหรับแต่ละเวิร์กโฟลว์)