GitHub Actions에서 AWS에 배포할 때 Access Key를 Repository Secret에 저장하고 있다면, 그 Key는 누가 마지막으로 교체했는지, 어떤 권한이 붙어 있는지 확인해볼 필요가 있습니다. 팀원이 퇴사해도 Key는 남아 있고, 유출되면 교체할 때까지 무제한으로 사용됩니다. OIDC(OpenID Connect)는 이 문제를 구조적으로 해결합니다. 장기 자격 증명을 저장하지 않고, 실행 시점에 단기 토큰을 발급받아 사용하는 방식입니다.
핵심 요약
- OIDC 기반 인증은 장기 자격 증명(Access Key, Service Account Key) 자체를 제거하여 유출 위험을 구조적으로 줄입니다.
- GitHub Actions, EKS Pod, GKE Pod 모두 동일한 원리로 동작합니다: 워크로드가 OIDC 토큰을 발급받고, Cloud Provider가 검증 후 임시 자격 증명을 교환합니다.
- AWS는 IRSA(기존)와 Pod Identity(신규) 두 가지 방식을 제공하며, 신규 클러스터에는 Pod Identity가 권장됩니다.
- Azure는 Workload Identity Federation으로 GitHub Actions와 AKS Pod 모두 동일한 패턴을 사용합니다.
- GCP는 Workload Identity Federation으로 GitHub Actions를, Workload Identity for GKE로 Pod를 연결합니다.
- 설계 시 핵심 판단 기준: 토큰 범위 제한(audience, subject), 최소 권한 IAM Role, 멀티 계정 구조에서의 Role Chaining입니다.
1. 왜 OIDC인가: 장기 자격 증명의 구조적 문제
5명으로 구성된 DevOps 팀이 GitHub Actions로 AWS, Azure 리소스에 배포하고, EKS 클러스터에서 S3와 DynamoDB에 접근하는 상황을 생각해봅니다.
장기 자격 증명(Access Key, Client Secret) 방식으로 운영하면 시간이 지날수록 다음 문제가 누적됩니다.
- 교체 부담: Key를 90일마다 교체하려면 모든 워크플로우와 Kubernetes Secret을 동시에 업데이트해야 합니다. 하나라도 누락하면 배포가 실패합니다.
- 유출 시 피해 범위: Key가 유출되면 교체 완료까지 무제한 사용됩니다. CloudTrail 로그로 발견하더라도 이미 피해가 발생한 후입니다.
- 범위 제어 한계: 같은 Key를 여러 워크플로우에서 공유하면, 한 워크플로우가 침해되었을 때 다른 워크플로우의 리소스까지 영향받습니다.
- 감사 추적 어려움: 누가 언제 Key를 생성했고 어디에 배포했는지 추적이 어렵습니다.
OIDC는 이 문제를 "자격 증명을 저장하지 않는다"는 설계로 해결합니다.
2. OIDC 동작 원리: 토큰 교환의 구조
OIDC 기반 인증의 핵심은 토큰 교환(Token Exchange) 패턴입니다. 모든 Cloud Provider에서 동일한 3단계로 동작합니다.
토큰 교환 흐름
1. 워크로드(GitHub Actions Runner, EKS Pod)가 자체 OIDC Provider로부터 JWT를 발급받음
2. JWT를 Cloud Provider의 STS(Security Token Service)에 제출
3. Cloud Provider가 JWT를 검증하고, 조건이 맞으면 임시 자격 증명(1시간)을 발급
JWT 내부 구조
GitHub Actions가 발급하는 OIDC 토큰의 주요 클레임:
{
"iss": "https://token.actions.githubusercontent.com",
"sub": "repo:my-org/my-repo:ref:refs/heads/main",
"aud": "sts.amazonaws.com",
"ref": "refs/heads/main",
"repository": "my-org/my-repo",
"repository_owner": "my-org",
"job_workflow_ref": "my-org/my-repo/.github/workflows/deploy.yml@refs/heads/main",
"exp": 1718000000,
"iat": 1717999400
}
| 클레임 | 역할 |
|---|---|
iss (Issuer) |
토큰 발급자. Cloud Provider가 이 URL에서 공개 키를 가져와 서명 검증 |
sub (Subject) |
워크로드의 신원. Trust Policy에서 조건 매칭에 사용 |
aud (Audience) |
토큰의 대상. 의도하지 않은 서비스에서 토큰 재사용을 방지 |
exp / iat |
토큰 유효 기간. 일반적으로 5~15분 |
Cloud Provider는 iss로 공개 키를 조회하고, 서명을 검증한 뒤, sub와 aud 조건이 Trust Policy와 일치하는지 확인합니다. 모든 조건이 통과하면 임시 자격 증명을 발급합니다.
보안 설계 포인트
- 토큰 수명 최소화: JWT 자체는 5~15분, 발급받는 임시 자격 증명은 기본 1시간입니다. 유출되어도 피해 시간이 제한됩니다.
- Subject 범위 제한:
sub클레임으로 특정 저장소, 브랜치, 환경만 허용할 수 있습니다.repo:my-org/*처럼 와일드카드를 넓게 잡으면 OIDC의 보안 이점이 줄어듭니다. - Audience 검증:
aud를 명시적으로 지정해야 다른 서비스에서 토큰을 재사용하는 confused deputy 공격을 방지합니다.
3. GitHub Actions + AWS OIDC 연동
설정 구조
GitHub Actions에서 AWS 리소스에 접근하려면 3가지를 설정합니다.
- AWS에 OIDC Provider 등록: GitHub의 토큰 발급 서버를 AWS가 신뢰하도록 등록
- IAM Role 생성: Trust Policy로 어떤 저장소/브랜치에서 Assume 가능한지 제한
- 워크플로우에서 토큰 요청:
permissions: id-token: write를 선언하고 Action 사용
Terraform으로 OIDC Provider + IAM Role 생성
# OIDC Provider 등록
resource "aws_iam_openid_connect_provider" "github" {
url = "https://token.actions.githubusercontent.com"
client_id_list = ["sts.amazonaws.com"]
thumbprint_list = ["1b511abead59c6ce207077c0bf0e0043b1382612"]
}
# IAM Role - Trust Policy에서 저장소와 브랜치 제한
resource "aws_iam_role" "github_actions" {
name = "github-actions-deploy"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Federated = aws_iam_openid_connect_provider.github.arn
}
Action = "sts:AssumeRoleWithWebIdentity"
Condition = {
StringEquals = {
"token.actions.githubusercontent.com:aud" = "sts.amazonaws.com"
}
StringLike = {
"token.actions.githubusercontent.com:sub" = "repo:my-org/my-app:ref:refs/heads/main"
}
}
}
]
})
}
# 필요한 권한만 부여 (예: ECR Push + ECS Deploy)
resource "aws_iam_role_policy_attachment" "ecr_push" {
role = aws_iam_role.github_actions.name
policy_arn = "arn:aws:iam::123456789012:policy/ECRPushPolicy"
}
워크플로우 설정
name: Deploy to AWS
on:
push:
branches: [main]
permissions:
id-token: write # OIDC 토큰 요청 권한
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: arn:aws:iam::123456789012:role/github-actions-deploy
aws-region: ap-northeast-2
- run: aws sts get-caller-identity # 임시 자격 증명 확인
aws-actions/configure-aws-credentials의 현재 최신 버전은 v6.2.0입니다. v6부터 Node 24 런타임을 사용하며, role-chaining과 custom session tag를 지원합니다.
멀티 계정 구조: Role Chaining
대부분의 운영 환경에서는 AWS 계정이 여러 개입니다. 하나의 Hub 계정에 OIDC Trust를 설정하고, 실제 워크로드 계정으로 Role Chaining하는 패턴이 일반적입니다.
steps:
# 1단계: Hub 계정의 Role을 OIDC로 Assume
- uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: arn:aws:iam::111111111111:role/github-oidc-hub
aws-region: ap-northeast-2
# 2단계: Hub Role에서 워크로드 계정의 Role로 Chaining
- uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: arn:aws:iam::222222222222:role/workload-deploy
role-chaining: true
aws-region: ap-northeast-2
이 구조의 장점은 OIDC Provider를 1개 계정에만 등록하면 되므로 관리 포인트가 줄어든다는 점입니다. 다만 Hub Role의 Trust Policy가 과도하게 넓으면 어떤 저장소든 모든 워크로드 계정에 접근할 수 있으므로, Hub Role에서도 sub 조건을 저장소 단위로 제한해야 합니다.
4. EKS 워크로드 인증: IRSA vs Pod Identity
EKS에서 Pod가 AWS 리소스에 접근할 때도 OIDC 기반 인증을 사용합니다. 현재 두 가지 방식이 있습니다.
IRSA (IAM Roles for Service Accounts)
2019년에 출시된 방식으로, EKS 클러스터의 OIDC Provider를 IAM에 등록하고 ServiceAccount와 IAM Role을 연결합니다.
# ServiceAccount에 IAM Role ARN을 annotation으로 연결
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app
namespace: production
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-app-role
# IAM Role Trust Policy - 특정 클러스터의 특정 ServiceAccount만 허용
resource "aws_iam_role" "my_app" {
name = "my-app-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Federated = "arn:aws:iam::123456789012:oidc-provider/oidc.eks.ap-northeast-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE"
}
Action = "sts:AssumeRoleWithWebIdentity"
Condition = {
StringEquals = {
"oidc.eks.ap-northeast-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub" = "system:serviceaccount:production:my-app"
"oidc.eks.ap-northeast-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud" = "sts.amazonaws.com"
}
}
}
]
})
}
Pod Identity (2023년 출시)
Pod Identity는 OIDC Provider를 직접 관리하지 않고, AWS가 제공하는 Pod Identity Agent가 노드에서 자격 증명을 중개합니다.
# Pod Identity Association 생성
aws eks create-pod-identity-association \
--cluster-name my-cluster \
--namespace production \
--service-account my-app \
--role-arn arn:aws:iam::123456789012:role/my-app-role
# Terraform으로 Pod Identity Association 설정
resource "aws_eks_pod_identity_association" "my_app" {
cluster_name = aws_eks_cluster.main.name
namespace = "production"
service_account = "my-app"
role_arn = aws_iam_role.my_app.arn
}
Pod Identity의 IAM Role Trust Policy는 클러스터별 OIDC URL이 아닌 범용 Principal을 사용합니다:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "pods.eks.amazonaws.com"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}
IRSA vs Pod Identity 선택 기준
| 기준 | IRSA | Pod Identity |
|---|---|---|
| OIDC Provider 관리 | 클러스터마다 등록 필요 | 불필요 (AWS 관리) |
| Trust Policy | 클러스터별 OIDC URL 포함 → 복잡 | 범용 Service Principal → 단순 |
| 멀티 클러스터 | 클러스터마다 Trust Policy 수정 필요 | 1개 Role을 여러 클러스터에서 재사용 가능 |
| Session Tag | 수동 설정 필요 | 자동 태깅 (클러스터명, namespace, SA) |
| ABAC 지원 | 제한적 | Session Tag 기반 ABAC 지원 |
| 최소 EKS 버전 | 1.14+ | 1.24+ |
| 추가 Agent | 불필요 | Pod Identity Agent DaemonSet 필요 |
설계 판단: 신규 EKS 클러스터(1.24+)에서는 Pod Identity가 운영 복잡도를 줄여줍니다. 특히 멀티 클러스터 환경에서는 Trust Policy 관리 부담이 크게 줄어듭니다. 기존 클러스터에서 IRSA가 이미 동작 중이라면 당장 마이그레이션할 필요는 없으며, 신규 워크로드부터 Pod Identity를 적용하는 점진적 전환이 적합합니다.
5. Azure Workload Identity Federation
Azure에서도 동일한 패턴으로 GitHub Actions와 AKS Pod에서 OIDC 인증을 사용합니다. Azure는 이를 Workload Identity Federation이라 부릅니다.
GitHub Actions + Azure 연동
# 1. App Registration 생성
az ad app create --display-name "github-actions-deploy"
# 2. Federated Credential 추가 (GitHub OIDC 신뢰)
az ad app federated-credential create \
--id <app-object-id> \
--parameters '{
"name": "github-main-branch",
"issuer": "https://token.actions.githubusercontent.com",
"subject": "repo:my-org/my-app:ref:refs/heads/main",
"audiences": ["api://AzureADTokenExchange"]
}'
# 3. Service Principal에 역할 할당
az role assignment create \
--assignee <app-client-id> \
--role "Contributor" \
--scope "/subscriptions/<sub-id>/resourceGroups/my-rg"
워크플로우:
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- run: az resource list --resource-group my-rg
Azure의 경우 client-id, tenant-id, subscription-id는 Secret에 저장하지만, 이들은 식별자일 뿐 자격 증명이 아닙니다. Client Secret이나 Certificate 없이 OIDC 토큰만으로 인증이 완료됩니다.
AKS Workload Identity
AKS에서는 azure-workload-identity 프로젝트를 통해 Pod가 Azure 리소스에 접근합니다.
# ServiceAccount에 Workload Identity annotation
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app
namespace: production
annotations:
azure.workload.identity/client-id: "<managed-identity-client-id>"
# Pod에 Workload Identity 라벨 추가
apiVersion: v1
kind: Pod
metadata:
labels:
azure.workload.identity/use: "true"
spec:
serviceAccountName: my-app
containers:
- name: app
image: my-app:latest
6. GCP Workload Identity Federation
GitHub Actions + GCP 연동
# 1. Workload Identity Pool 생성
gcloud iam workload-identity-pools create "github-pool" \
--location="global" \
--display-name="GitHub Actions Pool"
# 2. OIDC Provider 추가
gcloud iam workload-identity-pools providers create-oidc "github-provider" \
--location="global" \
--workload-identity-pool="github-pool" \
--display-name="GitHub OIDC" \
--issuer-uri="https://token.actions.githubusercontent.com" \
--attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository" \
--attribute-condition="assertion.repository_owner == 'my-org'"
# 3. Service Account에 workloadIdentityUser 역할 바인딩
gcloud iam service-accounts add-iam-policy-binding "deploy@my-project.iam.gserviceaccount.com" \
--role="roles/iam.workloadIdentityUser" \
--member="principalSet://iam.googleapis.com/projects/123456/locations/global/workloadIdentityPools/github-pool/attribute.repository/my-org/my-app"
워크플로우:
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: google-github-actions/auth@v2
with:
workload_identity_provider: "projects/123456/locations/global/workloadIdentityPools/github-pool/providers/github-provider"
service_account: "deploy@my-project.iam.gserviceaccount.com"
- uses: google-github-actions/setup-gcloud@v2
- run: gcloud run deploy my-service --image gcr.io/my-project/my-app
GKE Workload Identity
GKE에서는 Workload Identity Federation for GKE가 기본으로 활성화됩니다. Pod의 Kubernetes ServiceAccount를 GCP IAM Service Account에 연결합니다.
# Kubernetes ServiceAccount와 GCP Service Account 바인딩
gcloud iam service-accounts add-iam-policy-binding \
"my-app@my-project.iam.gserviceaccount.com" \
--role="roles/iam.workloadIdentityUser" \
--member="serviceAccount:my-project.svc.id.goog[production/my-app]"
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app
namespace: production
annotations:
iam.gke.io/gcp-service-account: my-app@my-project.iam.gserviceaccount.com
GKE Workload Identity는 OIDC Provider를 별도로 등록할 필요 없이, 클러스터 생성 시 --workload-pool 옵션만 활성화하면 됩니다.
7. 멀티 클라우드 OIDC 설계 비교
| 구분 | AWS | Azure | GCP |
|---|---|---|---|
| GitHub OIDC Trust 등록 | IAM OIDC Provider | App Registration + Federated Credential | Workload Identity Pool + Provider |
| 토큰 교환 엔드포인트 | STS (AssumeRoleWithWebIdentity) | Microsoft Entra ID | STS (ExchangeToken) |
| Kubernetes Pod 인증 | IRSA 또는 Pod Identity | AKS Workload Identity | GKE Workload Identity |
| Trust 범위 제한 | Condition (sub, aud) | subject + audiences | attribute-condition |
| 임시 자격 증명 수명 | 기본 1시간 (최대 12시간) | 기본 1시간 | 기본 1시간 |
| 멀티 계정/구독/프로젝트 | Role Chaining | 구독별 Role Assignment | Cross-project IAM binding |
설계 시 공통 원칙
- Subject 범위를 최소화: 저장소 + 브랜치 + 환경 단위로 제한.
repo:my-org/*처럼 와일드카드를 조직 전체로 열면 안 됩니다. - 환경별 Role 분리: 개발/스테이징/프로덕션 환경마다 별도 Role을 생성하고, GitHub Environment Protection Rules와 연동합니다.
- 감사 로그 활성화: 임시 자격 증명으로 수행한 작업도 CloudTrail, Azure Activity Log, GCP Cloud Audit Logs에 기록됩니다. Session Name에 워크플로우 정보를 포함하면 추적이 쉽습니다.
- 임시 자격 증명 수명 최소화: 기본 1시간이지만, 빌드/배포 작업이 30분 내에 끝난다면
role-duration-seconds를 줄여 피해 시간을 제한할 수 있습니다.
8. 실무 시나리오: 스타트업 CI/CD + EKS 배포 파이프라인
3명의 DevOps 팀이 운영하는 환경을 가정합니다.
- GitHub 조직:
startup-corp - AWS 계정: Shared (Hub), Dev, Production 3개
- EKS 클러스터: Dev 1개, Production 1개
- 배포 대상: 3개 마이크로서비스 (user-api, order-api, payment-api)
설계 구조
GitHub Actions (OIDC)
└─ Hub 계정 Role (github-oidc-hub)
├─ Dev 계정 Role (dev-deploy) ← Role Chaining
└─ Prod 계정 Role (prod-deploy) ← Role Chaining + Environment 보호 규칙
EKS Pod (Pod Identity)
├─ user-api ServiceAccount → user-api-role (DynamoDB 읽기)
├─ order-api ServiceAccount → order-api-role (SQS 송수신)
└─ payment-api ServiceAccount → payment-api-role (KMS 복호화 + S3 쓰기)
왜 이렇게 설계하는가
- Hub 계정 분리: OIDC Provider를 1곳에만 등록하면 GitHub 인증서 thumbprint 변경 시 1곳만 업데이트합니다.
- 환경별 Role 분리: Dev Role에는
terraform plan수준의 읽기 권한만, Prod Role에는terraform apply권한을 부여합니다. - Pod 단위 최소 권한: payment-api가 침해되어도 DynamoDB에는 접근할 수 없습니다. 각 Pod는 자신의 서비스에 필요한 권한만 가집니다.
- Pod Identity 선택 이유: 2개 클러스터에서 같은 Role을 재사용할 수 있어 Trust Policy 관리가 단순합니다. Session Tag로 어떤 클러스터, 어떤 namespace에서 호출했는지 CloudTrail에 자동 기록됩니다.
9. 주의사항과 트러블슈팅
GitHub Actions OIDC 관련
| 증상 | 원인 | 해결 |
|---|---|---|
Not authorized to perform: sts:AssumeRoleWithWebIdentity |
Trust Policy의 sub 조건 불일치 | github.event_name, github.ref를 확인. PR 이벤트는 ref:refs/pull/*/merge 형태 |
permissions: id-token: write 추가했는데 토큰이 안 나옴 |
Fork된 저장소에서는 OIDC 토큰 미발급 | Fork PR 워크플로우에서는 OIDC 사용 불가 |
| 토큰 만료 에러 | 워크플로우 실행 시간이 토큰 유효 기간 초과 | role-duration-seconds를 늘리거나, 장시간 작업은 Step을 분리 |
EKS IRSA/Pod Identity 관련
| 증상 | 원인 | 해결 |
|---|---|---|
Pod에서 An error occurred (AccessDenied) |
ServiceAccount annotation 누락 또는 Trust Policy 불일치 | kubectl describe sa + IAM Role Trust Policy 확인 |
| Pod Identity Agent가 CrashLoop | EKS 클러스터 버전이 1.24 미만 | 클러스터 업그레이드 필요 |
No OpenIDConnect provider found |
OIDC Provider가 IAM에 미등록 (IRSA) | aws eks describe-cluster로 OIDC URL 확인 후 등록 |
Subject 클레임 참고
GitHub Actions의 sub 클레임은 트리거 이벤트에 따라 달라집니다:
| 이벤트 | sub 형태 |
|---|---|
push (main) |
repo:org/repo:ref:refs/heads/main |
push (tag) |
repo:org/repo:ref:refs/tags/v1.0.0 |
pull_request |
repo:org/repo:pull_request |
environment |
repo:org/repo:environment:production |
workflow_dispatch |
repo:org/repo:ref:refs/heads/main |
프로덕션 배포에는 environment 기반 sub를 사용하고, GitHub Environment Protection Rules(Required Reviewers)와 결합하면 승인 없이 프로덕션에 배포되는 것을 방지할 수 있습니다.
10. OIDC vs 기존 방식: 언제 OIDC를 선택할 수 없는가
OIDC가 일반적으로 더 안전한 방식이지만, 모든 상황에 적합하지는 않습니다.
| 상황 | OIDC 사용 가능 | 대안 |
|---|---|---|
| GitHub Actions → AWS/Azure/GCP | ✅ | — |
| EKS/AKS/GKE Pod → 동일 Cloud | ✅ | — |
| Jenkins → AWS | ✅ (Jenkins OIDC Plugin 사용) | — |
| GitHub Actions → 외부 SaaS API (Slack, Datadog 등) | ❌ | Repository/Environment Secret |
| On-premise 서버 → Cloud | 조건부 (IdP 필요) | IAM User + IP 제한 + MFA |
| Lambda → 다른 AWS 서비스 | 불필요 (Execution Role 사용) | — |
OIDC를 지원하지 않는 외부 서비스에 대해서는 여전히 Secret 기반 인증이 필요합니다. 이 경우에도 Environment Secret + Rotation Policy를 적용하여 위험을 줄입니다.
관련 글
- GitHub Actions에서 Secret을 안전하게 관리하는 방법 — OIDC를 포함한 전체 Secret 관리 전략
- GitHub Actions로 Docker 이미지를 빌드하고 배포하기 — OIDC를 적용한 실제 배포 파이프라인
- IAM과 RBAC 차이: AWS, Azure, GCP 기준으로 이해하기 — OIDC Role에 붙이는 IAM 권한 설계의 기본
참고 문서
'Security' 카테고리의 다른 글
| IAM과 RBAC 차이: AWS, Azure, GCP 기준으로 이해하기 (0) | 2026.06.08 |
|---|---|
| DevSecOps란 무엇인가: CI/CD에 보안을 통합하는 방법 (0) | 2026.06.07 |
| GitHub Actions에서 Secret을 안전하게 관리하는 방법 (0) | 2026.06.06 |
| AWS IAM Role과 Policy 차이: 권한을 설계하는 두 가지 축 (0) | 2026.05.29 |
| 클라우드 보안 기본 원칙: 최소 권한, 네트워크 격리, 감사 로그 (0) | 2026.05.28 |