Skip to content

Commit bab769a

Browse files
authored
Merge pull request #1 from awslabs/feat/repo-guardrails
feat: Add repo-level guardrails and CI workflows
2 parents 4c61e54 + 4914dbf commit bab769a

19 files changed

Lines changed: 600 additions & 6 deletions

.bandit-baseline.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]

.github/CODEOWNERS

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Repo infrastructure - only admins can modify
2+
/.github/ @awslabs/startups-admins
3+
mise.toml @awslabs/startups-admins
4+
dprint.json @awslabs/startups-admins
5+
.pre-commit-config.yaml @awslabs/startups-admins
6+
.gitleaks.toml @awslabs/startups-admins
7+
.semgrep.yaml @awslabs/startups-admins
8+
.markdownlint-cli2.yaml @awslabs/startups-admins
9+
10+
# Team folders
11+
/migrate/ @awslabs/startups-migrate

.github/ISSUE_TEMPLATE/rfc---request-for-comments.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,28 @@ about: Propose a new feature, artifact, or major update
44
title: 'RFC: <your proposal title>'
55
labels: needs-triage, rfc-proposal
66
assignees: ayn-builds
7-
87
---
98

109
## Summary
10+
1111
<!-- One paragraph describing the proposal -->
1212

1313
## Motivation
14+
1415
<!-- Why is this needed? What problem does it solve? -->
1516

1617
## Proposed Solution
18+
1719
<!-- Describe your approach in detail -->
1820

1921
## Alternatives Considered
22+
2023
<!-- What other approaches did you evaluate and why were they rejected? -->
2124

2225
## Open Questions
26+
2327
<!-- What is still undecided or needs community input? -->
2428

2529
## Drawbacks
30+
2631
<!-- Any known trade-offs or risks? -->

.github/pull_request_template.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
## Description
2+
3+
<!-- Brief description of the changes -->
4+
5+
## Type of Change
6+
7+
- [ ] New plugin/power/tool
8+
- [ ] Bug fix
9+
- [ ] Enhancement to existing content
10+
- [ ] Documentation update
11+
- [ ] Guardrail/CI update
12+
13+
## Team Folder
14+
15+
<!-- Which top-level folder does this PR affect? -->
16+
17+
- [ ] `migrate/`
18+
- [ ] Other: ___
19+
20+
## Checklist
21+
22+
- [ ] I have read the [CONTRIBUTING.md](../CONTRIBUTING.md) guidelines
23+
- [ ] My changes do not include hardcoded secrets, credentials, or internal-only content
24+
- [ ] I have run `mise run build` locally and it passes
25+
- [ ] I have updated documentation if needed
26+
- [ ] My changes are scoped to my team's folder only

.github/workflows/build.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Build
2+
3+
on:
4+
pull_request: {}
5+
workflow_dispatch: {}
6+
7+
permissions:
8+
actions: none
9+
contents: none
10+
11+
jobs:
12+
build:
13+
permissions:
14+
actions: read
15+
contents: read
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
20+
with:
21+
fetch-depth: 0
22+
23+
- name: Setup mise
24+
uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4.0.1
25+
with:
26+
cache: true
27+
28+
- name: Build
29+
run: mise run build
30+
31+
- name: Find mutations
32+
id: self_mutation
33+
run: |-
34+
git add .
35+
git diff --staged --patch --exit-code > repo.patch || echo "self_mutation_happened=true" >> $GITHUB_OUTPUT
36+
shell: bash
37+
38+
- name: Upload patch
39+
if: steps.self_mutation.outputs.self_mutation_happened
40+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
41+
with:
42+
name: repo.patch
43+
path: repo.patch
44+
overwrite: true
45+
46+
- name: Fail build on mutation
47+
if: steps.self_mutation.outputs.self_mutation_happened
48+
run: |-
49+
echo "::error::Files were changed during build (see build log). Please run the build locally and commit the changes."
50+
cat repo.patch
51+
exit 1
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
name: Security Scanners
2+
3+
on:
4+
schedule:
5+
- cron: '12 15 * * *'
6+
workflow_dispatch:
7+
push:
8+
branches: [main]
9+
pull_request:
10+
branches: [main]
11+
12+
permissions:
13+
actions: none
14+
contents: none
15+
16+
jobs:
17+
gitleaks:
18+
permissions:
19+
actions: read
20+
contents: read
21+
security-events: write
22+
runs-on: ubuntu-latest
23+
env:
24+
GITLEAKS_VERSION: "8.30.0"
25+
steps:
26+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
27+
with:
28+
fetch-depth: 0
29+
- name: Install gitleaks
30+
run: |
31+
curl -sSfL "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" | tar -xz;
32+
sudo mv gitleaks /usr/local/bin/;
33+
gitleaks --version;
34+
- name: Run gitleaks
35+
id: gitleaks
36+
run: |
37+
set +e
38+
gitleaks git --config=.gitleaks.toml --baseline-path=.gitleaks-baseline.json --report-path=gitleaks-report.sarif --report-format=sarif .
39+
GITLEAKS_EXIT=$?
40+
set -e
41+
echo "exit_code=$GITLEAKS_EXIT" >> "$GITHUB_OUTPUT"
42+
exit 0
43+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
44+
if: always()
45+
with:
46+
name: gitleaks.sarif
47+
path: gitleaks-report.sarif
48+
if-no-files-found: error
49+
- uses: github/codeql-action/upload-sarif@5e7a52feb2a3dfb87f88be2af33b9e2275f48de6 # v4.32.2
50+
continue-on-error: true
51+
with:
52+
sarif_file: gitleaks-report.sarif
53+
- if: steps.gitleaks.outputs.exit_code != '0'
54+
run: |
55+
echo "::error::gitleaks found secrets"
56+
exit ${{ steps.gitleaks.outputs.exit_code }}
57+
58+
bandit:
59+
permissions:
60+
actions: read
61+
contents: read
62+
security-events: write
63+
runs-on: ubuntu-latest
64+
steps:
65+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
66+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
67+
with:
68+
python-version: '3.x'
69+
- name: Run bandit
70+
id: bandit
71+
run: |
72+
pip install "bandit[sarif]==1.9.3"
73+
set +e
74+
bandit -r . -f sarif -o bandit-report.sarif
75+
BANDIT_EXIT=$?
76+
set -e
77+
echo "exit_code=$BANDIT_EXIT" >> "$GITHUB_OUTPUT"
78+
exit 0
79+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
80+
if: always()
81+
with:
82+
name: bandit.sarif
83+
path: bandit-report.sarif
84+
if-no-files-found: error
85+
- uses: github/codeql-action/upload-sarif@5e7a52feb2a3dfb87f88be2af33b9e2275f48de6 # v4.32.2
86+
continue-on-error: true
87+
with:
88+
sarif_file: bandit-report.sarif
89+
- if: steps.bandit.outputs.exit_code != '0'
90+
run: |
91+
echo "::error::bandit found security issues"
92+
exit ${{ steps.bandit.outputs.exit_code }}
93+
94+
semgrep:
95+
permissions:
96+
actions: read
97+
contents: read
98+
security-events: write
99+
runs-on: ubuntu-latest
100+
steps:
101+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
102+
with:
103+
fetch-depth: 0
104+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
105+
with:
106+
python-version: '3.x'
107+
- name: Run semgrep
108+
id: semgrep
109+
env:
110+
BASELINE_SHA: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha }}
111+
run: |
112+
pip install "semgrep==1.151.0"
113+
BASELINE_ARGS=""
114+
if [ -n "$BASELINE_SHA" ]; then
115+
BASELINE_ARGS="--baseline-commit $BASELINE_SHA"
116+
fi
117+
set +e
118+
semgrep scan --oss-only --metrics=off --config=r/all \
119+
--exclude-rule="ai.generic.detect-generic-ai-anthprop.detect-generic-ai-anthprop" \
120+
--exclude-rule="ai.generic.detect-generic-ai-oai.detect-generic-ai-oai" \
121+
--sarif-output semgrep-report.sarif $BASELINE_ARGS
122+
SEMGREP_EXIT=$?
123+
set -e
124+
echo "exit_code=$SEMGREP_EXIT" >> "$GITHUB_OUTPUT"
125+
exit 0
126+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
127+
if: always()
128+
with:
129+
name: semgrep.sarif
130+
path: semgrep-report.sarif
131+
if-no-files-found: error
132+
- uses: github/codeql-action/upload-sarif@5e7a52feb2a3dfb87f88be2af33b9e2275f48de6 # v4.32.2
133+
continue-on-error: true
134+
with:
135+
sarif_file: semgrep-report.sarif
136+
- if: steps.semgrep.outputs.exit_code != '0'
137+
run: |
138+
echo "::error::semgrep found security issues"
139+
exit ${{ steps.semgrep.outputs.exit_code }}
140+
141+
checkov:
142+
permissions:
143+
actions: read
144+
contents: read
145+
security-events: write
146+
runs-on: ubuntu-latest
147+
steps:
148+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
149+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
150+
with:
151+
python-version: '3.x'
152+
- name: Run checkov
153+
id: checkov
154+
run: |
155+
pip install "checkov==3.2.500"
156+
set +e
157+
checkov -d . --output sarif --output-file-path .
158+
CHECKOV_EXIT=$?
159+
mv results_sarif.sarif checkov-report.sarif || true
160+
set -e
161+
echo "exit_code=$CHECKOV_EXIT" >> "$GITHUB_OUTPUT"
162+
exit 0
163+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
164+
if: always()
165+
with:
166+
name: checkov.sarif
167+
path: checkov-report.sarif
168+
if-no-files-found: error
169+
- uses: github/codeql-action/upload-sarif@5e7a52feb2a3dfb87f88be2af33b9e2275f48de6 # v4.32.2
170+
continue-on-error: true
171+
with:
172+
sarif_file: checkov-report.sarif
173+
- if: steps.checkov.outputs.exit_code != '0'
174+
run: |
175+
echo "::error::checkov found IaC issues"
176+
exit ${{ steps.checkov.outputs.exit_code }}

.github/workflows/stale.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Stale Issues
2+
3+
on:
4+
schedule:
5+
- cron: '0 0 * * *'
6+
7+
permissions:
8+
issues: write
9+
pull-requests: write
10+
11+
jobs:
12+
stale:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
16+
with:
17+
stale-issue-message: >
18+
This issue has been automatically marked as stale because it has not had
19+
recent activity. It will be closed if no further activity occurs within 7 days.
20+
stale-pr-message: >
21+
This PR has been automatically marked as stale because it has not had
22+
recent activity. It will be closed if no further activity occurs within 7 days.
23+
days-before-stale: 60
24+
days-before-close: 7
25+
stale-issue-label: stale
26+
stale-pr-label: stale

.gitignore

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Dependencies
2+
node_modules/
3+
4+
# Build outputs
5+
dist/
6+
build/
7+
__pycache__/
8+
9+
# Tool caches
10+
.dprint/
11+
.ruff_cache/
12+
.mise/
13+
14+
# Temporary files
15+
.tmp/
16+
*.log
17+
18+
# OS files
19+
.DS_Store
20+
Thumbs.db
21+
22+
# IDE
23+
.idea/
24+
.vscode/
25+
*.swp
26+
*.swo
27+
28+
# Environment
29+
.env
30+
.env.local
31+
32+
# Claude
33+
.claude/settings.local.json
34+
35+
# Migration artifacts (generated at runtime by plugins)
36+
.migration/

.gitleaks-baseline.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]

.gitleaks.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Gitleaks Configuration
2+
# https://github.com/gitleaks/gitleaks
3+
4+
title = "gitleaks config"
5+
6+
[extend]
7+
useDefault = true
8+
9+
[allowlist]
10+
description = "Global allowlist"
11+
paths = [
12+
'''\.gitleaksignore$''',
13+
'''\.gitleaks-baseline\.json$''',
14+
]

0 commit comments

Comments
 (0)