ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [GitHub Actions][OIDC] enterprise custom issuer 뒤 AWS trust policy에서 aud mismatch와 sub scope drift가 같이 보일 때 어떤 claim snapshot부터 다시 남기나
    기타개발지식/풀스택개발 2026. 8. 12. 09:17

    IT 리서치 노트

    [GitHub Actions][OIDC] enterprise custom issuer 뒤 AWS trust policy에서 aud mismatch와 sub scope drift가 같이 보일 때 어떤 claim snapshot부터 다시 남기나

    GitHub Actions OIDC에서 enterprise custom issuer를 켠 뒤 AWS role assumption이 흔들리면 많은 팀이 issuer URL 한 줄부터 다시 본다. 하지만 2026년 8월 11일 기준 GitHub 공식 문서를 다시 보면 AWS는 OIDC custom claims를 직접 trust anchor로 쓰지 못하고, audience와 subject 조건이 여전히 기본축이며, 2026년 7월 15일 이후 저장소는 immutable subject 형식까지 달라질 수 있다. 이 글은 enterprise custom issuer 뒤 AWS trust policy에서 aud mismatch와 sub scope drift가 같이 보일 때 어떤 claim snapshot부터 다시 남기는 편이 incident 분리를 빠르게 만드는지 정리한 것이다.

    1. 개요

    결론부터 말하면 AWS branch에서는 iss, aud, sub, immutable subject 사용 여부를 한 레코드로 먼저 저장하고, repo_property_*는 그다음 evidence 층으로 분리하는 편이 맞다. custom issuer rollout 뒤 장애가 나도 AWS 쪽 첫 판단은 여전히 audience와 subject 조건이기 때문이다.

    즉 첫 질문은 "custom property가 토큰에 붙었나"보다 "이 run의 aud와 sub가 현재 trust policy가 기대하는 형식과 정확히 같은가"다. 이 순서를 바꾸면 AWS trust policy를 넓히거나 repo_property 설정을 손대면서도 실제 원인 증거를 잃기 쉽다.

    2. 어디서 실제로 막히는가

    실무에서 가장 자주 꼬이는 지점은 네 가지다. 첫째, enterprise custom issuer를 켠 뒤 cloud provider issuer URL만 다시 맞추고 aud 값은 기본 action 입력값을 그대로 둔 채 넘어간다. 둘째, 저장소가 immutable subject 형식으로 바뀌었는데도 예전 repo:ORG/REPO:ref:... 패턴만 떠올리고 trust policy를 그대로 둔다. 셋째, environment 기반 subject와 branch 기반 subject를 같은 표로 적지 않아 어느 scope에서 drift가 났는지 구분하지 못한다. 넷째, repo_property 기반 ABAC 구상을 같이 하면서도 AWS에서는 custom claims 지원이 없다는 제약을 앞단에 적지 않아 triage 순서가 뒤섞인다.

    GitHub AWS OIDC 가이드는 AWS에서 custom claims 지원이 없다고 직접 적고, OIDC reference는 aud와 sub를 함께 조건으로 두는 것이 기본이라고 설명한다. 같은 reference는 또 2026년 7월 15일 이후 저장소에서 immutable owner/repository ID가 들어가는 형식을 예시로 보여 준다. 이 셋을 같이 읽으면 AWS branch의 첫 분기는 custom issuer 자체보다 현재 aud와 현재 sub 문자열을 정확히 저장하는 일이라는 점이 분명해진다.

    문제는 많은 팀이 claim snapshot을 남기지 않고 cloud console 에러 한 줄로만 사건을 닫는다는 점이다. 그러면 같은 role이 어떤 run에서는 통과하고 어떤 run에서는 실패할 때, audience 입력 차이인지 environment context 변화인지 immutable subject opt-in 효과인지 분해가 잘 안 된다. 특히 AWS trust policy는 문자열 비교에 가깝기 때문에 한 글자 차이만 나도 결과가 완전히 갈린다.

    • 증상: 같은 workflow인데 어떤 run은 통과하고 어떤 run은 AWS assume-role이 실패한다.
    • 실패: issuer 변경만 기록하고 aud와 sub 실제값은 저장하지 않는다.
    • 막힘: immutable subject 형식 전환 시점을 run 기록과 연결하지 않는다.
    • 누락: repo_property 계획과 AWS custom-claims 제약을 같은 문서에 적지 않는다.
    증상 먼저 볼 곳 짧은 해석
    role assumption이 전부 실패한다 iss, aud IdP 또는 audience 조건부터 어긋났을 가능성이 크다
    일부 branch·environment만 실패한다 sub, environment, ref scope drift 또는 immutable subject 형식 차이를 먼저 본다
    ABAC property 계획과 결과가 엇갈린다 repo_property_*, AWS 제약 메모 AWS에서 trust anchor로 직접 못 쓰는지 다시 적는다

    3. 실무에서 적용하는 순서

    실무에서는 다섯 단계가 가장 짧다. 먼저 실패한 run에서 JWT를 안전하게 decode해 iss, aud, sub, repository, ref, environment, run_attempt를 한 번에 저장한다. 두 번째로 AWS trust policy의 StringEquals 또는 StringLike 조건을 바로 옆에 붙인다. 세 번째로 해당 저장소가 immutable subject 형식을 쓰는지 기록한다. 네 번째로 repo_property inclusion 여부는 별도 evidence 레코드로 남긴다. 마지막으로 rerun 성공/실패 차이를 claim snapshot과 같이 묶어 재현성을 확보한다.

    1. 실패한 run의 iss, aud, sub, ref, environment를 같은 시각에 저장한다.
    2. AWS trust policy의 aud와 sub 조건을 바로 옆에 붙여 diff를 본다.
    3. immutable subject 형식 사용 여부와 저장소 생성 시점을 적는다.
    4. repo_property_*는 보조 evidence 항목으로만 남긴다.
    5. rerun 결과와 run_attempt 차이를 같은 티켓에 보관한다.

    이 구조를 잡아 두면 같은 AWS 오류라도 triage 길이가 눈에 띄게 짧아진다. 예를 들어 aud가 sts.amazonaws.com이 아니면 action 입력이나 audience 커스터마이징부터 다시 보면 되고, aud는 맞는데 sub가 repo:org@owner_id/repo@repo_id:... 형식으로 바뀌어 있으면 trust policy가 과거 형식에 묶여 있었는지 바로 확인할 수 있다. 반대로 둘 다 맞는데 property 기반 분기만 안 맞는다면 그때 비로소 repo_property evidence 로그를 꺼내 보는 식이다.

    운영 메모 예시
    oidc_provider=github-enterprise-custom-issuer
    snapshot_time=2026-08-11T20:41:03+09:00
    iss=https://token.actions.githubusercontent.com
    aud=sts.amazonaws.com
    sub=repo:example-org/example-repo@987654:ref:refs/heads/main
    trust_aud=sts.amazonaws.com
    trust_sub=repo:example-org/example-repo:ref:refs/heads/main
    immutable_subject=true
    repo_property_workspace_id=ws-abc123
    rerun_result=failed

    이미 include_claim_keys drift 글이 token shape 전체를 보는 감각을 다뤘다면, 이번 글은 그중 AWS branch에서 가장 먼저 남겨야 할 최소 claim set만 다시 좁힌 셈이다. 또 sub 조건과 repo_property 확장 글과 같이 보면 subject 확장과 AWS 제약을 같은 맥락에서 정리할 수 있다.

    4. 공식 문서와 예시 화면으로 확인하기

    첫 공식 화면은 AWS 가이드의 가장 강한 제약이다. enterprise custom issuer를 켠 뒤에도 AWS 쪽에서 먼저 봐야 할 것은 custom claim을 세밀하게 받느냐가 아니라, 아직 custom claims 자체를 trust anchor로 삼을 수 없다는 점이다.

    GitHub AWS OIDC 가이드는 AWS에서 OIDC custom claims 지원이 없다고 먼저 못 박는다.
    GitHub AWS OIDC 가이드는 AWS에서 OIDC custom claims 지원이 없다고 먼저 못 박는다.

    이 문장 때문에 aud mismatch와 sub drift를 분리하지 않으면 원인이 repo_property 쪽인지, 애초에 AWS trust condition 기본축이 틀어진 것인지 한참 섞이게 된다. 이번 글의 핵심은 그래서 custom issuer rollout 뒤에도 첫 snapshot을 aud·sub 중심으로 남기는 이유다.

    두 번째 공식 화면은 GitHub OIDC reference의 기본 원칙이다. audience와 subject는 보통 같이 조건에 걸고, subject는 branch나 environment 같은 맥락값을 이어 붙인 문자열이라는 점을 다시 확인해야 한다.

    GitHub OIDC reference는 aud와 sub를 함께 조건에 두는 것이 기본이라고 설명한다.
    GitHub OIDC reference는 aud와 sub를 함께 조건에 두는 것이 기본이라고 설명한다.

    실무에서 cloud error 한 줄만 보면 aud mismatch인지 sub drift인지 분리가 잘 안 된다. 하지만 이 화면처럼 두 조건은 나란히 설계된다는 점을 먼저 받아들이면, snapshot도 최소 두 축으로 쪼개서 저장해야 한다는 결론이 자연스럽게 나온다.

    세 번째 공식 화면은 이번 주제에서 날짜가 실제로 중요한 부분이다. 2026년 7월 15일 이후 생성된 저장소나 immutable subject claims에 opt-in한 저장소는 sub 형식이 달라질 수 있다고 GitHub 문서가 명시한다.

    GitHub 문서는 2026년 7월 15일 이후 저장소에서 immutable subject 형식이 달라질 수 있다고 안내한다.
    GitHub 문서는 2026년 7월 15일 이후 저장소에서 immutable subject 형식이 달라질 수 있다고 안내한다.

    즉 aud 값은 그대로인데 sub 문자열만 달라져 role assumption이 깨지는 시나리오가 현실적으로 생긴다. 이 경우 issuer를 다시 손대기보다 현재 저장소가 어떤 sub 형식을 쓰는지 먼저 캡처하는 편이 훨씬 빠르다.

    네 번째 자료는 실제 triage 표다. 같은 AWS 오류여도 aud mismatch는 trust provider 또는 action audience 쪽으로, sub drift는 repository context나 immutable subject 형식 쪽으로 갈린다.

    AWS OIDC 장애를 aud mismatch와 sub drift로 나눠 읽는 비교표다.
    AWS OIDC 장애를 aud mismatch와 sub drift로 나눠 읽는 비교표다.

    이미 cloud provider trust allowlist 글이 멀티 클라우드 앞단을 다뤘다면, 이번 표는 그중 AWS branch만 따로 좁히는 후속편이다. 또 sub 조건과 repo_property 확장 글에서 한 단계 더 들어가 aud와 immutable subject를 나누는 흐름이 된다.

    다섯 번째 자료는 가장 실용적인 claim snapshot 예시다. 로그에 토큰 전문을 남길 필요는 없고, 운영 판단에 필요한 claim만 안전하게 decode해서 저장하면 된다.

    AWS branch triage에 필요한 최소 OIDC claim snapshot 예시다.
    AWS branch triage에 필요한 최소 OIDC claim snapshot 예시다.

    여기서 중요한 것은 `aud`와 `sub`를 같은 레코드에 넣되, `repo_property_*`는 보조 evidence로 분리하는 점이다. AWS가 custom claims를 trust anchor로 직접 받지 못하는 상황에서는 더더욱 이 분리가 회고 품질을 좌우한다.

    마지막 자료는 실제 순서 메모다. 로그가 급할 때는 눈앞의 AWS 에러를 캡처하고 끝내기 쉬운데, 그보다 먼저 어떤 값을 같은 시각에 묶어 저장할지 정해 두는 편이 재현성이 높다.

    custom issuer 뒤 AWS OIDC triage에서 먼저 남길 항목을 정리한 체크리스트다.
    custom issuer 뒤 AWS OIDC triage에서 먼저 남길 항목을 정리한 체크리스트다.

    이 정도만 남겨도 role trust policy를 넓히기 전에 issuer·aud·sub 어디가 실제로 변했는지 분기할 수 있다. 특히 2026년 7월 15일 이후 저장소처럼 sub 형식이 달라질 수 있는 경우에는 snapshot 자체가 가장 중요한 증거가 된다.

    5. 주의사항과 리스크

    첫 번째 리스크는 repo_property 기반 ABAC 설계를 하다가 AWS trust policy까지 같은 방식으로 바로 옮길 수 있다고 생각하는 것이다. 문서상 AWS는 custom claims 지원이 없으므로, 적어도 첫 triage 단계에서는 aud와 sub를 앞에 두는 편이 맞다. 두 번째 리스크는 immutable subject 형식 변경을 migration 항목으로 남기지 않는 것이다. 저장소 생성 시점이나 opt-in 시점을 잊으면, 며칠 뒤에는 왜 sub 문자열이 달라졌는지 근거를 찾기 어려워진다.

    세 번째 리스크는 rerun 결과를 남기지 않은 채 trust policy만 여러 번 바꾸는 것이다. 이러면 어떤 변경이 실제로 문제를 풀었는지, 단지 다른 run context가 들어와 우연히 통과한 것인지 구분이 안 된다. 운영 메모에는 최소한 issuer, aud, sub, trust 조건, immutable subject 여부, rerun 결과가 함께 있어야 한다.

    • AWS branch의 첫 anchor는 여전히 aud와 sub다.
    • immutable subject 형식 전환은 별도 migration 메모로 남긴다.
    • repo_property는 evidence 로그로 분리하고, rerun 결과와 같이 본다.

    6. 결론

    enterprise custom issuer 뒤 AWS trust가 흔들릴 때는 cloud console 에러보다 claim snapshot이 먼저다. 같은 run에서 iss, aud, sub, immutable subject 여부를 같이 저장하고 trust policy 조건과 바로 비교하면, audience mismatch인지 subject scope drift인지 훨씬 빨리 가른다. 그 뒤에야 repo_property evidence를 보는 편이 incident 분리와 회고 품질 둘 다 낫다.

    여기서 sub 형식 자체가 왜 달라졌는지까지 바로 이어서 확인하려면, 방금 정리한 후속편인 저장소 생성 시점과 rename·transfer 때문에 immutable sub 형식이 바뀔 때 AWS trust policy를 다시 고치는 글을 함께 보는 편이 좋다. 특히 2026년 7월 15일 이후 생성 저장소나 최근 이름 변경이 있었던 저장소는 claim snapshot만으로 끝내지 말고 sub format migration까지 같이 기록해야 incident 재발을 줄일 수 있다.

    • 첫 snapshot은 iss, aud, sub, run_attempt 중심으로 남긴다.
    • immutable subject 형식 여부를 항상 같이 적는다.
    • repo_property는 trust anchor가 아니라 보조 evidence로 분리한다.

    7. 참고 링크

    1. https://docs.github.com/en/actions/how-tos/secure-your-work/security-harden-deployments/oidc-in-aws
    2. https://docs.github.com/en/actions/reference/security/oidc
    3. https://docs.github.com/en/actions/concepts/security/openid-connect
Designed by Tistory.