Skip to content

Commit 40dc461

Browse files
repo hygiene: SECURITY, CODEOWNERS, CI, link-check, dependabot, Pages
Responsible disclosure policy. Code owners for security-sensitive paths. CI for markdown, YAML, GitHub Actions, and Semgrep rule validation. Lychee link checker with blocking offline pass on PRs and a weekly scheduled full check that files maintenance issues. Dependabot for github-actions and the docs toolchain. mkdocs-material build and deploy-pages workflow; Pages source switches from Jekyll to GitHub Actions in repository settings.
1 parent 3f646cb commit 40dc461

13 files changed

Lines changed: 773 additions & 0 deletions

.github/CODEOWNERS

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Code owners for review assignment.
2+
# Documentation: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
3+
4+
* @maverick-hackz
5+
6+
# Security-sensitive areas. Same owner today; listed explicitly so that
7+
# future co-maintainers do not silently inherit ownership.
8+
/devsecops/semgrep-rules/ @maverick-hackz
9+
/devsecops/ci-templates/ @maverick-hackz
10+
/devsecops/k8s-policies/ @maverick-hackz
11+
/SECURITY.md @maverick-hackz
12+
/.github/ @maverick-hackz

.github/ISSUE_TEMPLATE/bug.yml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: Defect or inaccuracy
2+
description: Report incorrect, outdated, or unsafe guidance in the handbook.
3+
title: "[bug]: <short description>"
4+
labels: ["bug", "needs-triage"]
5+
body:
6+
- type: markdown
7+
attributes:
8+
value: |
9+
Use this template to report a defect in the handbook content,
10+
Semgrep rules, CI/CD templates, or Kubernetes policies. For
11+
security vulnerabilities in the materials (insecure defaults,
12+
false-negative detection logic), prefer the private channel in
13+
`SECURITY.md` instead of a public issue.
14+
15+
- type: input
16+
id: location
17+
attributes:
18+
label: Affected file or rule
19+
description: Path, or rule identifier for Semgrep findings.
20+
placeholder: "secure-coding/python/deserialization-pickle.md"
21+
validations:
22+
required: true
23+
24+
- type: textarea
25+
id: problem
26+
attributes:
27+
label: What is wrong, and why
28+
description: >-
29+
Describe the inaccuracy and the consequence of acting on the current
30+
text. State the assumption that breaks or the misconception it
31+
creates.
32+
validations:
33+
required: true
34+
35+
- type: textarea
36+
id: source
37+
attributes:
38+
label: Authoritative source for the correction
39+
description: >-
40+
OWASP, NIST, MITRE, RFC, or vendor documentation that supports the
41+
proposed correction. Blogs are supporting material, not primary
42+
sources.
43+
placeholder: |
44+
- RFC 7515 §10.7 (https://www.rfc-editor.org/rfc/rfc7515#section-10.7)
45+
- NVD entry for CVE-YYYY-NNNNN
46+
validations:
47+
required: true
48+
49+
- type: textarea
50+
id: suggested-text
51+
attributes:
52+
label: Suggested correction (optional)
53+
description: >-
54+
Drop-in text or a sketch of the fix. PRs are welcome instead of
55+
suggestions; both forms are accepted.
56+
57+
- type: checkboxes
58+
id: confirmations
59+
attributes:
60+
label: Pre-flight checks
61+
options:
62+
- label: I checked for an existing open or recently closed issue covering this defect.
63+
required: true
64+
- label: My report does not include internal or proprietary information.
65+
required: true
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
name: Content request
2+
description: Propose a new section, writeup, secure-coding entry, or framework mapping.
3+
title: "[content]: <short description>"
4+
labels: ["content", "needs-triage"]
5+
body:
6+
- type: markdown
7+
attributes:
8+
value: |
9+
Use this template to propose new material. Out of scope: offensive
10+
payloads and pentest cheatsheets (see CONTRIBUTING.md). Those
11+
belong in https://github.com/maverick-hackz/Workstation.
12+
13+
- type: dropdown
14+
id: section
15+
attributes:
16+
label: Target section
17+
options:
18+
- secure-coding/
19+
- threat-modeling/
20+
- secure-sdlc/
21+
- devsecops/
22+
- frameworks/
23+
- architecture/
24+
- tooling-evaluation/
25+
- writeups/
26+
- references/
27+
- new top-level section
28+
validations:
29+
required: true
30+
31+
- type: textarea
32+
id: scope
33+
attributes:
34+
label: Proposed scope
35+
description: >-
36+
What does the new material cover, and what does it intentionally
37+
exclude? Two or three sentences.
38+
validations:
39+
required: true
40+
41+
- type: textarea
42+
id: rationale
43+
attributes:
44+
label: Why this fits the handbook
45+
description: >-
46+
How does the proposal map to the audiences listed in the README
47+
(AppSec engineers, developers, security architects, hiring
48+
managers evaluating depth)?
49+
validations:
50+
required: true
51+
52+
- type: textarea
53+
id: sources
54+
attributes:
55+
label: Primary sources you will cite
56+
description: OWASP, NIST, MITRE, RFC, or vendor documentation.
57+
placeholder: |
58+
- OWASP API Security Top 10 2023, API1:2023
59+
- NIST SP 800-204C
60+
- RFC 9449
61+
validations:
62+
required: true
63+
64+
- type: checkboxes
65+
id: confirmations
66+
attributes:
67+
label: Pre-flight checks
68+
options:
69+
- label: The proposal does not duplicate existing material in this repository.
70+
required: true
71+
- label: The proposal does not introduce offensive payloads or pentest cheatsheets.
72+
required: true
73+
- label: The proposal will follow the template in the target section's README.
74+
required: true
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Link rot (automated)
2+
description: Auto-generated by the weekly link-check workflow. Do not file manually.
3+
title: "link-rot: scheduled lychee report"
4+
labels: ["link-rot", "maintenance"]
5+
body:
6+
- type: markdown
7+
attributes:
8+
value: |
9+
This template is used by `.github/workflows/link-check.yml` when the
10+
scheduled run detects broken external links. The body is replaced
11+
with the lychee report at creation time. Manual reports of broken
12+
references should use the `Defect or inaccuracy` template instead.
13+
14+
- type: textarea
15+
id: report
16+
attributes:
17+
label: lychee report
18+
value: |
19+
<!-- populated by the workflow -->

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<!--
2+
Per CONTRIBUTING.md, a pull request description should answer four
3+
questions. Replace each prompt below with a concise answer.
4+
-->
5+
6+
## 1. What changed?
7+
8+
<!-- One or two sentences. -->
9+
10+
## 2. Which sections of the handbook were touched and why?
11+
12+
<!-- List the affected paths (secure-coding/, devsecops/, frameworks/, ...)
13+
and the motivation for each. -->
14+
15+
## 3. Primary sources
16+
17+
<!-- OWASP, NIST, MITRE, RFC, vendor documentation. Blogs are supporting
18+
material, not primary sources. -->
19+
20+
## 4. Validation
21+
22+
- [ ] `markdownlint-cli2 "**/*.md"` (or affected files only)
23+
- [ ] `yamllint .` (if any `.yml` / `.yaml` under `devsecops/` was touched)
24+
- [ ] `semgrep --config devsecops/semgrep-rules/ --validate` (if rules touched)
25+
- [ ] `semgrep --config devsecops/semgrep-rules/ --test` (if rules touched)
26+
- [ ] `kubectl --dry-run=client apply -f <file>` or `kubeconform` (if K8s
27+
manifests touched)
28+
- [ ] `lychee --offline <files>` (internal relative links resolve)
29+
30+
## Notes for the reviewer
31+
32+
<!-- Anything that affects how this should be evaluated: known limitations,
33+
follow-ups planned in a separate PR, related issues. -->

.github/dependabot.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Dependabot configuration.
2+
# Documentation: https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
3+
#
4+
# Scope: GitHub Actions in .github/workflows/ (the handbook's own CI) and
5+
# Python dependencies in requirements-docs.txt (mkdocs-material + plugins).
6+
#
7+
# Out of scope: the educational CI templates under devsecops/ci-templates/.
8+
# Dependabot's github-actions ecosystem only inspects .github/workflows/, so
9+
# the templates are not touched automatically. They are versioned by hand
10+
# alongside the handbook prose that references them.
11+
12+
version: 2
13+
updates:
14+
- package-ecosystem: github-actions
15+
directory: /
16+
schedule:
17+
interval: weekly
18+
day: monday
19+
time: "06:00"
20+
timezone: Europe/Moscow
21+
open-pull-requests-limit: 5
22+
commit-message:
23+
prefix: deps
24+
labels:
25+
- dependencies
26+
- github-actions
27+
28+
- package-ecosystem: pip
29+
directory: /
30+
schedule:
31+
interval: weekly
32+
day: monday
33+
time: "06:00"
34+
timezone: Europe/Moscow
35+
open-pull-requests-limit: 3
36+
commit-message:
37+
prefix: deps
38+
labels:
39+
- dependencies
40+
- python

.github/workflows/ci.yml

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# CI for the handbook itself: markdown, YAML, GitHub Actions, and Semgrep
2+
# rule validation. Educational CI templates under devsecops/ci-templates/
3+
# are validated structurally by actionlint; they are not executed here.
4+
#
5+
# Action references are version tags by default. Dependabot is configured
6+
# in .github/dependabot.yml and will rewrite them as `<sha> # vN.M.K` in
7+
# follow-up PRs as updates roll in. This mirrors the supply-chain guidance
8+
# the handbook gives in devsecops/ci-templates/.
9+
10+
name: ci
11+
12+
on:
13+
push:
14+
branches: [main]
15+
pull_request:
16+
branches: [main]
17+
18+
permissions:
19+
contents: read
20+
21+
concurrency:
22+
group: ci-${{ github.ref }}
23+
cancel-in-progress: true
24+
25+
jobs:
26+
markdownlint:
27+
name: markdownlint
28+
runs-on: ubuntu-24.04
29+
steps:
30+
- name: Checkout
31+
uses: actions/checkout@v4
32+
- name: Run markdownlint-cli2
33+
uses: DavidAnson/markdownlint-cli2-action@v18
34+
with:
35+
globs: |
36+
**/*.md
37+
!**/node_modules/**
38+
39+
yamllint:
40+
name: yamllint
41+
runs-on: ubuntu-24.04
42+
steps:
43+
- name: Checkout
44+
uses: actions/checkout@v4
45+
- name: Set up Python
46+
uses: actions/setup-python@v5
47+
with:
48+
python-version: "3.12"
49+
- name: Install yamllint
50+
run: pip install --no-cache-dir 'yamllint==1.35.1'
51+
- name: Run yamllint
52+
# Relaxed config: long lines and missing document-start markers are
53+
# acceptable in educational YAML snippets. Real violations
54+
# (truthy, indentation, trailing-spaces) still fail.
55+
run: |
56+
yamllint --strict -d '{
57+
extends: default,
58+
rules: {
59+
line-length: {max: 120, level: warning},
60+
document-start: disable,
61+
comments-indentation: disable,
62+
truthy: {allowed-values: ["true", "false"], check-keys: false}
63+
}
64+
}' devsecops/ .github/
65+
66+
actionlint:
67+
name: actionlint
68+
runs-on: ubuntu-24.04
69+
steps:
70+
- name: Checkout
71+
uses: actions/checkout@v4
72+
- name: Install actionlint
73+
# Uses the official installer script from the actionlint repository,
74+
# which downloads a release binary matching the pinned version.
75+
# Replace the version-only pin with a release binary checksum if you
76+
# need stricter supply-chain assurances; see the handbook's own
77+
# devsecops/ci-templates/ for that pattern.
78+
run: |
79+
bash <(curl -sSL https://raw.githubusercontent.com/rhysd/actionlint/v1.7.7/scripts/download-actionlint.bash) 1.7.7
80+
echo "ACTIONLINT_BIN=$(pwd)/actionlint" >> "$GITHUB_ENV"
81+
- name: Lint handbook workflows
82+
run: |
83+
"$ACTIONLINT_BIN" -color .github/workflows/*.yml
84+
- name: Lint educational templates (advisory)
85+
# Educational templates may intentionally omit elements (for example,
86+
# `permissions:` is sometimes shown in a later step of the prose).
87+
# Treat findings as advisory so they do not block contributions.
88+
continue-on-error: true
89+
run: |
90+
if compgen -G "devsecops/ci-templates/github-actions/*.yml" > /dev/null; then
91+
"$ACTIONLINT_BIN" -color devsecops/ci-templates/github-actions/*.yml
92+
else
93+
echo "no github-actions templates found"
94+
fi
95+
96+
semgrep-rules:
97+
name: semgrep rule validate and test
98+
runs-on: ubuntu-24.04
99+
steps:
100+
- name: Checkout
101+
uses: actions/checkout@v4
102+
- name: Set up Python
103+
uses: actions/setup-python@v5
104+
with:
105+
python-version: "3.12"
106+
- name: Install Semgrep
107+
run: pip install --no-cache-dir 'semgrep==1.96.0'
108+
- name: Validate rules
109+
run: semgrep --config devsecops/semgrep-rules/ --validate
110+
- name: Test rules
111+
# Tests require <rule>.test.<ext> fixture files in semgrep's expected
112+
# layout. If no fixtures are present, this step is a no-op rather
113+
# than a failure: rule-test fixtures are tracked separately and may
114+
# be introduced after rules. The job still fails if fixtures exist
115+
# and tests fail.
116+
run: |
117+
if find devsecops/semgrep-rules -name '*.test.*' -print -quit | grep -q .; then
118+
semgrep --config devsecops/semgrep-rules/ --test
119+
else
120+
echo "no semgrep test fixtures found; skipping --test"
121+
fi

0 commit comments

Comments
 (0)