Skip to content

Commit f7ebf2d

Browse files
authored
Update docs (#97)
1 parent 99fe01f commit f7ebf2d

3 files changed

Lines changed: 316 additions & 115 deletions

File tree

docs/aws.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,19 @@ aws iam create-open-id-connect-provider \
2828
> **Note:** A `--thumbprint-list` parameter is no longer required. AWS validates GitHub's OIDC tokens directly without certificate pinning. See [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials) for details.
2929
3030
**Step 2: Create the trust policy file** (`cleancloud-trust-policy.json`)
31+
32+
Choose the subject format that matches how your GitHub Actions workflow runs:
33+
34+
| Workflow trigger | Subject claim to use |
35+
|---|---|
36+
| Branch push (e.g. `main`) | `repo:<ORG>/<REPO>:ref:refs/heads/main` |
37+
| Pull request | `repo:<ORG>/<REPO>:pull_request` |
38+
| GitHub Environment | `repo:<ORG>/<REPO>:environment:<ENV_NAME>` |
39+
40+
> ⚠️ **Common mistake:** If your workflow uses `environment: production`, GitHub sends the `environment` subject claim — not the `ref` one. Using the wrong format causes `AccessDenied` when assuming the role. See [OIDC subject mismatch](#oidc-subject-claim-mismatch) in Troubleshooting.
41+
42+
**For branch-based workflows:**
43+
3144
```json
3245
{
3346
"Version": "2012-10-17",
@@ -47,6 +60,29 @@ aws iam create-open-id-connect-provider \
4760
}
4861
```
4962

63+
**For GitHub Environment workflows:**
64+
65+
```json
66+
{
67+
"Version": "2012-10-17",
68+
"Statement": [{
69+
"Effect": "Allow",
70+
"Principal": {
71+
"Federated": "arn:aws:iam::<ACCOUNT_ID>:oidc-provider/token.actions.githubusercontent.com"
72+
},
73+
"Action": "sts:AssumeRoleWithWebIdentity",
74+
"Condition": {
75+
"StringEquals": {
76+
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
77+
"token.actions.githubusercontent.com:sub": "repo:<YOUR_ORG>/<YOUR_REPO>:environment:<YOUR_ENV_NAME>"
78+
}
79+
}
80+
}]
81+
}
82+
```
83+
84+
> 💡 **Tip:** To allow multiple triggers (branch push and GitHub Environment), list both subject values in the same `StringEquals` condition — see [OIDC subject mismatch](#oidc-subject-claim-mismatch) in Troubleshooting.
85+
5086
Replace:
5187
- `<ACCOUNT_ID>` — Your AWS account ID
5288
- `<YOUR_ORG>/<YOUR_REPO>` — Your GitHub organization and repository
@@ -364,6 +400,10 @@ cleancloud scan --provider aws --region us-east-1 --output json --output-file re
364400
365401
# CSV (spreadsheet-friendly, 11 core columns)
366402
cleancloud scan --provider aws --region us-east-1 --output csv --output-file results.csv
403+
404+
# Markdown (paste into GitHub PRs, Slack, or issues)
405+
cleancloud scan --provider aws --all-regions --output markdown
406+
cleancloud scan --provider aws --all-regions --output markdown --output-file results.md
367407
```
368408

369409
**JSON schema, examples, and CSV column reference:** See [`ci.md`](ci.md#output-formats)
@@ -372,6 +412,64 @@ cleancloud scan --provider aws --region us-east-1 --output csv --output-file res
372412

373413
## Troubleshooting
374414

415+
### OIDC Subject Claim Mismatch
416+
417+
**Symptom:** `Error assuming role` or `AccessDenied` during the AWS credentials step, even though the IAM role and OIDC provider exist.
418+
419+
**Cause:** The subject claim in your IAM role trust policy does not match what GitHub actually sends in the JWT token. GitHub generates different subject claims depending on how your workflow is triggered.
420+
421+
**The three subject formats:**
422+
423+
| Workflow uses | GitHub sends | Trust policy `sub` condition |
424+
|---|---|---|
425+
| Branch push to `main` | `repo:org/repo:ref:refs/heads/main` | `repo:<ORG>/<REPO>:ref:refs/heads/main` |
426+
| Pull request trigger | `repo:org/repo:pull_request` | `repo:<ORG>/<REPO>:pull_request` |
427+
| `environment: production` | `repo:org/repo:environment:production` | `repo:<ORG>/<REPO>:environment:production` |
428+
429+
**Fix — check your workflow trigger and update the trust policy:**
430+
431+
If your workflow has `environment:` set:
432+
433+
```yaml
434+
jobs:
435+
cleancloud:
436+
environment: production # ← this changes the subject claim
437+
```
438+
439+
Update the trust policy `sub` condition to match:
440+
441+
```json
442+
"token.actions.githubusercontent.com:sub": "repo:<YOUR_ORG>/<YOUR_REPO>:environment:production"
443+
```
444+
445+
**Multiple triggers — allow both subject formats in one trust policy:**
446+
447+
```json
448+
{
449+
"Version": "2012-10-17",
450+
"Statement": [{
451+
"Effect": "Allow",
452+
"Principal": {
453+
"Federated": "arn:aws:iam::<ACCOUNT_ID>:oidc-provider/token.actions.githubusercontent.com"
454+
},
455+
"Action": "sts:AssumeRoleWithWebIdentity",
456+
"Condition": {
457+
"StringEquals": {
458+
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
459+
"token.actions.githubusercontent.com:sub": [
460+
"repo:<YOUR_ORG>/<YOUR_REPO>:ref:refs/heads/main",
461+
"repo:<YOUR_ORG>/<YOUR_REPO>:environment:production"
462+
]
463+
}
464+
}
465+
}]
466+
}
467+
```
468+
469+
> 💡 GitHub Environments are the recommended approach for production pipelines — they add deployment protection rules, required reviewers, and environment-scoped secrets on top of OIDC.
470+
471+
---
472+
375473
### "No credentials found"
376474

377475
```bash

0 commit comments

Comments
 (0)