Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: CodeQL

# CodeQL static analysis for Go. Runs on every PR, every push to main,
# and weekly to catch new query packs landing upstream. Findings appear
# in the Security tab; default-severity ERROR also fails the PR check.
#
# Why this AND Semgrep? Different rule packs catch different classes of
# bugs — Semgrep is great at custom org-policy patterns, CodeQL is better
# at dataflow-heavy queries (taint sinks, SSRF, SQLi-style). They overlap
# but the union finds more.

on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
# Sunday 04:23 UTC — off-peak, off-Monday-morning.
- cron: '23 4 * * 0'
workflow_dispatch:

# Cancel in-progress runs for the same PR when a new commit lands.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
analyze:
name: Analyze Go
runs-on: ubuntu-24.04
timeout-minutes: 30
permissions:
contents: read
security-events: write # upload SARIF to the Security tab
actions: read # CodeQL templates fetch workflow metadata

strategy:
fail-fast: false
matrix:
language: [go]

steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

# Pin Go to the version declared in go.mod. Without this, CodeQL
# Autobuild uses the runner's bundled Go (older than our 1.25.x
# directive), which fails the compile and surfaces as a CI red
# rather than a real finding (gemini round-1 P2).
- name: Set up Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
with:
go-version-file: go.mod
cache: false

- name: Initialize CodeQL
uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4
with:
languages: ${{ matrix.language }}
# security-extended adds queries beyond the default "security
# and quality" pack — taint tracking, less-common sink types,
# crypto misuses. Worth the extra ~2 min run-time for an OSS
# supply-chain tool.
queries: security-extended

- name: Autobuild
uses: github/codeql-action/autobuild@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4

- name: Perform analysis
uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4
with:
category: /language:${{ matrix.language }}
68 changes: 68 additions & 0 deletions .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: OpenSSF Scorecard

# OpenSSF Scorecard runs a battery of OSS-project security checks
# (Branch-Protection, Token-Permissions, Pinned-Dependencies,
# Dangerous-Workflow, etc.) and reports a score 0-10. We surface
# findings via SARIF in the Security tab AND publish to the public
# Scorecard API (api.securityscorecards.dev) so consumers can audit
# our posture without us asking.
#
# We do NOT use this for PR gating — checks are advisory and the score
# moves on factors outside any one PR's diff.

on:
branch_protection_rule:
schedule:
# Wednesday 09:17 UTC — mid-week so any regression caught by a
# branch-protection change has time to be reverted before weekend.
- cron: '17 9 * * 3'
push:
branches: [main]
workflow_dispatch:

# At-most-one scheduled run.
concurrency:
group: scorecard-${{ github.ref }}
cancel-in-progress: false

permissions:
contents: read

jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-24.04
permissions:
contents: read
# Required to upload SARIF to the Security tab.
security-events: write
# Required to publish results to securityscorecards.dev.
id-token: write

steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Run analysis
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
with:
results_file: results.sarif
results_format: sarif
# Publish to api.securityscorecards.dev so the badge + history
# are public. Required for the Scorecard badge to work.
publish_results: true

- name: Upload SARIF
uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4
with:
sarif_file: results.sarif
category: scorecard

- name: Upload artifact (debugging)
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: scorecard-results
path: results.sarif
retention-days: 30
82 changes: 82 additions & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# https://docs.github.com/en/repositories/managing-your-repositories-settings-and-customization/customizing-your-repository/about-code-owners
#
# CODEOWNERS for simple-container-com/api.
#
# IMPORTANT — semantics: when multiple users are listed on the same
# pattern, GitHub treats them as ALTERNATIVES, not a conjunction. A PR
# satisfies the CODEOWNERS gate once ANY one listed owner approves.
# To genuinely require approvals from BOTH leads on sensitive paths,
# configure a branch protection rule / Ruleset that sets:
# - "Require review from Code Owners"
# - "Required approving reviews" ≥ 2
# That's a repo-admin UI setting; this file can't express it.
#
# What this file DOES enforce:
# - GitHub auto-requests review from a code owner when a PR touches
# a matching file.
# - If the matching review-count rule is set in the admin UI, a PR
# cannot merge without enough code-owner approvals.
#
# Listing both leads on a pattern widens the review pool — either lead
# can sign off; both don't have to (unless the admin UI rule is set).
#
# Tip: GitHub picks the LAST matching pattern in this file for a given
# file path — ordering matters. Put broad defaults at the top and
# specific high-sensitivity globs at the bottom so they win.

# ---------------------------------------------------------------------
# Default — every file pulls in at least one lead for review.
# ---------------------------------------------------------------------
* @Cre-eD @smecsia

# ---------------------------------------------------------------------
# CI / supply-chain — sensitive paths. Multi-reviewer gating depends
# on the branch-protection setting described in the header. Touching
# these files changes how every release is built and how secrets
# reach the runner.
# ---------------------------------------------------------------------
/.github/ @Cre-eD @smecsia
/.github/workflows/ @Cre-eD @smecsia
/.github/actions/ @Cre-eD @smecsia
/.github/dependabot.yml @Cre-eD @smecsia

# ---------------------------------------------------------------------
# Image build context.
# ---------------------------------------------------------------------
/*.Dockerfile @Cre-eD @smecsia
/welder.yaml @Cre-eD @smecsia
/sc.sh @Cre-eD @smecsia

# ---------------------------------------------------------------------
# Security pipeline source — code that signs, scans, attests, and
# decides what gets blocked. Tamper with this and the whole consumer
# supply chain weakens.
# ---------------------------------------------------------------------
/pkg/security/ @Cre-eD @smecsia

# ---------------------------------------------------------------------
# Secrets / config plumbing.
# ---------------------------------------------------------------------
/pkg/api/secrets/ @Cre-eD @smecsia
/pkg/cmd/cmd_secrets/ @Cre-eD @smecsia

# ---------------------------------------------------------------------
# Cloud provisioning — IAM and resource defaults that ship to every
# consumer account.
# ---------------------------------------------------------------------
/pkg/clouds/pulumi/aws/ @Cre-eD @smecsia
/pkg/clouds/pulumi/gcp/ @Cre-eD @smecsia

# ---------------------------------------------------------------------
# Module graph — dep bumps need security review (see
# `feedback_sc_ci_tools_step` for the CI-quirk caveat).
# ---------------------------------------------------------------------
/go.mod @Cre-eD @smecsia
/go.sum @Cre-eD @smecsia
/tools.go @Cre-eD @smecsia

# ---------------------------------------------------------------------
# This policy + ownership file itself.
# ---------------------------------------------------------------------
/SECURITY.md @Cre-eD @smecsia
/CODEOWNERS @Cre-eD @smecsia
78 changes: 78 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Security Policy

Simple Container (`sc`) is an OSS supply-chain tool that runs in consumer
CI/CD and provisions cloud resources in customer accounts. A vulnerability
in this codebase can propagate downstream to every consumer, so we treat
all reports as high priority.

## Supported versions

Security fixes are issued for the **most recent calver release** (the
tag pushed by [`.github/workflows/push.yaml`][push] on every merge to
`main`) and back-ported to the latest `vYYYY.M.x` line only when the
fix is non-trivial. Older versions receive no patches; consumers should
pin to a recent release tag (or a SHA) and update via Dependabot /
[`integrail/devops/.github/actions/install-sc`][install-sc] (or
equivalent) on at least a monthly cadence.

| Version | Supported |
|---|---|
| `vYYYY.M.x` latest | ✅ |
| Previous calver release on the same month line | ✅ (best-effort back-port) |
| Anything older | ❌ |

## Reporting a vulnerability

**Do not file a public issue.** Use one of these channels in order of
preference:

1. **[GitHub Security Advisory][gsa]** — preferred. Private to maintainers,
integrates with CVE issuance and the GitHub-side fix workflow.
2. **Email** `security@simple-container.com` if you can't use GitHub
Security Advisories.

Please include:

- A description of the issue and the security impact you observed.
- The exact `sc` version (or commit SHA) affected.
- Reproduction steps or a proof of concept where possible.
- Whether you've shared the report with any third party.

We aim to acknowledge within **3 working days** and to ship a fix or
mitigation within **30 days** for HIGH/CRITICAL findings, **90 days**
for MEDIUM, longer for LOW. We'll keep you updated and credit you in
the advisory unless you ask to remain anonymous.

## Out of scope

These are intentionally outside the scope of this policy because they
sit in the *consumer's* infrastructure, not in this codebase:

- Vulnerabilities in the consumer's cloud account (IAM misconfig, etc.)
caused by how they *use* `sc`. Reach out to the relevant cloud
provider or to the consumer.
- Vulnerabilities in third-party tools `sc` invokes (`pulumi`, `cosign`,
`syft`, `trivy`, `grype`, `gcloud`, `kubectl`). Report those upstream.
- The Caddy / cloud-helpers / kubectl Docker images' *upstream* OS
packages — we re-roll on each release and the deferred CVE log is
documented in PRs at merge time.

## Hardening posture

The repository is hardened against the relevant supply-chain risks
covered by CIS, OWASP CICD Top 10, SLSA, NIST SSDF, and the OpenSSF
Scorecard. Current control status is tracked in the hardening pipeline
(image scan, SBOM, Semgrep, Dependabot, secret scan run on every PR
and merge). For details on the threat model and the controls that
ship with each release, see the PR history.

## Cryptographic primitives

`sc` uses **only** primitives from the Go standard library and a small
set of audited libraries (`cosign`, `sigstore-go`). We avoid rolling
our own crypto. The local security-scan cache uses HMAC-SHA256 with a
32-byte random per-cache key for tamper detection.

[push]: .github/workflows/push.yaml
[install-sc]: https://github.com/simple-container-com/actions/tree/main/install-sc
[gsa]: https://github.com/simple-container-com/api/security/advisories/new
Loading
Loading