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
11 changes: 11 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,17 @@ jobs:
shell: pwsh
run: ./scripts/sbom-validate-check.ps1 -SelfCheck

# Blocking C06 L33 Socket.dev posture evidence — hermetic SelfCheck only.
# Does not call Socket API or claim live org GitHub App install.
socket-posture:
name: Socket posture SelfCheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- name: Socket.dev posture + in-repo dependency scan anchors
shell: pwsh
run: ./scripts/socket-posture-check.ps1 -SelfCheck

# Blocking C06 L53 protected-environment checklist — hermetic SelfCheck only.
# Does not claim live GitHub Environment wiring or full SLSA Build L3 attestation.
slsa-protected-env:
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Follows [Keep a Changelog](https://keepachangelog.com/); versioning is [SemVer](

### Added

- Socket.dev supply-chain posture (C06 L33): `docs/ops/socket-posture.md`, `socket-posture.json`, `scripts/socket-posture-check.ps1 -SelfCheck`, blocking `security.yml` job, `tests/socket_posture.rs`.

- Wave-43 scope (396/402): consolidated `WAVE43_SCOPE.md` + `docs/ops/WAVE43_PERT.md` — five parallel carry-forward lanes (`w43-daemon-graph-hard`, `w43-jemalloc-default-on`, `w43-load-macro-gate`, `w43-sl-viewer-help`, `w43-socket-posture`) from Wave-42 deferred gaps.

- Blocking alloc-profile / dhat PR gate (C00 L8): `.github/workflows/alloc-profile-hard.yml`, expanded `alloc-profile-check.ps1 -SelfCheck` anchors, `tests/alloc_profile_hard.rs` (soft `ops-load` job retained).
Expand Down
1 change: 1 addition & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Critical supply-chain or remote-code issues may be accelerated at maintainer dis
- Advisory scanning: `cargo audit` job in .github/workflows/security.yml.
- SBOM upload: qgate uploads `sbom-cyclonedx` artifact from `target/sbom.cdx.json`.
- CVE feed subscription (GHSA + OSV + NVD): maintainer process and evidence links in [`docs/ops/cve-feed-subscription.md`](docs/ops/cve-feed-subscription.md). Hermetic proof: `pwsh ./scripts/cve-feed-check.ps1 -SelfCheck`.
- Socket.dev supply-chain posture (optional org GitHub App complement): policy SSOT in [`docs/ops/socket-posture.md`](docs/ops/socket-posture.md). Hermetic proof: `pwsh ./scripts/socket-posture-check.ps1 -SelfCheck`. Live org install is **not** attestable from this repository.

## Cryptography inventory

Expand Down
1 change: 1 addition & 0 deletions docs/ops/cve-feed-subscription.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This document does **not** claim maintainer 2FA enforcement (L36) — org-level
2FA is not verifiable from checkout (see [`branch-protection.md`](branch-protection.md)).

Related: [`SECURITY.md`](../../SECURITY.md) (reporting + supply-chain policy),
[`socket-posture.md`](socket-posture.md) (optional Socket.dev complement),
[`deny.toml`](../../deny.toml) (cargo-deny advisories),
[`.github/workflows/security.yml`](../../.github/workflows/security.yml)
(cargo-deny + cargo-audit), [`.github/dependabot.yml`](../../.github/dependabot.yml),
Expand Down
21 changes: 21 additions & 0 deletions docs/ops/socket-posture.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"schema_version": 1,
"purpose": "Socket.dev supply-chain telemetry posture (C06 L33 complement to cargo-deny/audit)",
"github_app": "Socket Security for GitHub",
"expected_pr_checks": [
"Socket Security: Pull Request Alerts",
"Socket Security: Project Report"
],
"in_repo_blocking": [
"cargo deny check",
"cargo audit",
"gitleaks",
"trufflehog"
],
"verify_command": "./scripts/socket-posture-check.ps1 -SelfCheck",
"not_verifiable_in_repo": [
"Socket.dev org API token",
"GitHub App install state",
"Live dashboard policy thresholds"
]
}
72 changes: 72 additions & 0 deletions docs/ops/socket-posture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Socket.dev supply-chain posture

Status: **C06 L33** complement — documents how SessionLedger aligns with
[Socket.dev](https://socket.dev) dependency-risk telemetry **alongside** in-repo
blocking scans (`cargo deny`, `cargo audit`, gitleaks, TruffleHog). Machine
proof: `pwsh ./scripts/socket-posture-check.ps1 -SelfCheck`.

Policy manifest: [`socket-posture.json`](socket-posture.json).

Related: [`SECURITY.md`](../../SECURITY.md),
[`cve-feed-subscription.md`](cve-feed-subscription.md),
[`.github/workflows/security.yml`](../../.github/workflows/security.yml),
[`deny.toml`](../../deny.toml).

## Layered controls

| Layer | Role | Evidence in this repo |
|-------|------|------------------------|
| **In-repo blocking** | Primary PR gate for Rust advisories + secrets | `cargo-deny`, `cargo-audit`, gitleaks, TruffleHog in `security.yml` |
| **GHSA/OSV/NVD feeds** | Maintainer triage beyond a single bot | [`cve-feed-subscription.md`](cve-feed-subscription.md) |
| **Socket.dev (optional org)** | Supply-chain behavior scoring on PRs when the GitHub App is installed | Expected check names in `socket-posture.json`; **not** enforced by this SelfCheck |

SessionLedger does **not** embed a Socket API token or run Socket CLI in CI.
When the org installs the Socket GitHub App, PRs may show **Socket Security: Pull Request Alerts** and **Project Report** checks (third-party; informational unless branch protection requires them).

## Maintainer process

### 1. Keep in-repo scans green (required)

Every PR / push to `main` runs [`.github/workflows/security.yml`](../../.github/workflows/security.yml):

- `cargo deny check` — advisory policy from [`deny.toml`](../../deny.toml)
- `cargo audit` — RustSec / GHSA-backed advisories
- gitleaks + TruffleHog — secret scanning

Triage failures before merging; do not rely on Socket alone to waive deny/audit hits.

### 2. Optional Socket.dev GitHub App (org)

1. Org admin installs **Socket Security for GitHub** on `KooshaPari/SessionLedger`.
2. Confirm PR checks include the names listed in [`socket-posture.json`](socket-posture.json).
3. Review Socket alerts as **supplementary** signal (typosquatting, install scripts,
risky postinstall) — cross-check against `cargo deny` / `cargo audit` before merge.
4. Record org install date in a maintainer note if branch protection later requires Socket checks.

### 3. When Socket is absent

In-repo `cargo-deny`, `cargo-audit`, Renovate/Dependabot, and
[`cve-feed-subscription.md`](cve-feed-subscription.md) remain the authoritative
dependency-risk surface. Absence of Socket checks is **not** a merge blocker
unless org policy adds them to required checks.

## SelfCheck gate

| Check | Status |
|-------|--------|
| `socket-posture-check.ps1 -SelfCheck` | **done** — docs + `security.yml` anchor |
| Live Socket API / org install | **NOT_VERIFIABLE_IN_REPO** |

Hermetic SelfCheck validates policy doc anchors, `SECURITY.md` cross-link,
`security.yml` job wiring, and complementary scan evidence paths. No network,
no Socket API token, no false claim of live org install.

## Done / unpaid

| Item | Status |
|------|--------|
| Policy SSOT + JSON manifest | **done** |
| Blocking `security.yml` SelfCheck job | **done** |
| `tests/socket_posture.rs` cargo wrapper | **done** |
| Live Socket org API automation | **unpaid** — creds / org |
| Branch-protection required Socket checks | **unpaid** — human Settings |
166 changes: 166 additions & 0 deletions scripts/socket-posture-check.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<#
.SYNOPSIS
Machine-check Socket.dev supply-chain posture doc anchors (C06 L33).

.DESCRIPTION
Verifies docs/ops/socket-posture.md + socket-posture.json document Socket.dev
as an optional org GitHub App complement to in-repo cargo-deny / cargo-audit /
gitleaks / TruffleHog. Cross-checks SECURITY.md, security.yml job wiring, and
CVE feed subscription links.
Hermetic: no network, no Socket API token, no org install attestation.

.PARAMETER SelfCheck
Explicit docs/path smoke (CI unit proof). Same checks as the default path.

.EXAMPLE
pwsh ./scripts/socket-posture-check.ps1 -SelfCheck
#>
[CmdletBinding()]
param(
[switch]$SelfCheck
)

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

$repoRoot = Split-Path -Parent $PSScriptRoot
$docPath = Join-Path $repoRoot "docs/ops/socket-posture.md"
$policyPath = Join-Path $repoRoot "docs/ops/socket-posture.json"
$cveFeedPath = Join-Path $repoRoot "docs/ops/cve-feed-subscription.md"
$securityPath = Join-Path $repoRoot "SECURITY.md"
$denyPath = Join-Path $repoRoot "deny.toml"
$securityWorkflow = Join-Path $repoRoot ".github/workflows/security.yml"
$selfPath = Join-Path $repoRoot "scripts/socket-posture-check.ps1"
$wrapperTest = Join-Path $repoRoot "tests/socket_posture.rs"

function Assert-File {
param(
[Parameter(Mandatory = $true)][string]$Path,
[Parameter(Mandatory = $true)][string]$Label
)
if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) {
throw "Missing $Label at '$Path'."
}
}

function Write-Check {
param([string]$Label, [bool]$Ok)
$mark = if ($Ok) { "PASS" } else { "FAIL" }
Write-Host " [$mark] $Label"
return $Ok
}

function Test-DocContains {
param(
[Parameter(Mandatory = $true)][string]$Doc,
[Parameter(Mandatory = $true)][string]$Needle,
[Parameter(Mandatory = $true)][string]$Label,
[string]$Context = "docs/ops/socket-posture.md"
)
$ok = $Doc.Contains($Needle)
[void](Write-Check -Label $Label -Ok $ok)
if (-not $ok) {
throw "$Context missing required anchor: '$Needle'"
}
}

Write-Host "Socket.dev posture check (C06 L33)"
if ($SelfCheck) {
Write-Host "Mode: SelfCheck (docs + evidence paths; no Socket API / no network)"
}

Assert-File -Path $docPath -Label "socket posture doc"
Assert-File -Path $policyPath -Label "socket posture policy JSON"
Assert-File -Path $cveFeedPath -Label "CVE feed subscription doc"
Assert-File -Path $securityPath -Label "SECURITY.md"
Assert-File -Path $denyPath -Label "deny.toml"
Assert-File -Path $securityWorkflow -Label "security workflow"
Assert-File -Path $selfPath -Label "socket posture check script"
Assert-File -Path $wrapperTest -Label "socket_posture.rs test wrapper"

$doc = Get-Content -LiteralPath $docPath -Raw
$policy = Get-Content -LiteralPath $policyPath -Raw
$cveFeed = Get-Content -LiteralPath $cveFeedPath -Raw
$security = Get-Content -LiteralPath $securityPath -Raw
$securityWf = Get-Content -LiteralPath $securityWorkflow -Raw

Write-Host "Socket posture doc anchors:"
Test-DocContains -Doc $doc -Needle "Socket.dev supply-chain posture" `
-Label "doc heading"
Test-DocContains -Doc $doc -Needle "**C06 L33**" `
-Label "C06 L33 status"
Test-DocContains -Doc $doc -Needle "## Layered controls" `
-Label "layered controls heading"
Test-DocContains -Doc $doc -Needle "Socket Security: Pull Request Alerts" `
-Label "expected PR check name"
Test-DocContains -Doc $doc -Needle "NOT_VERIFIABLE_IN_REPO" `
-Label "org install disclaimer"
Test-DocContains -Doc $doc -Needle "socket-posture-check.ps1" `
-Label "SelfCheck script reference"
Test-DocContains -Doc $doc -Needle "socket-posture-check.ps1 -SelfCheck" `
-Label "SelfCheck gate marked done"
Test-DocContains -Doc $doc -Needle "cargo deny" `
-Label "cargo-deny named"
Test-DocContains -Doc $doc -Needle "cargo audit" `
-Label "cargo-audit named"
Test-DocContains -Doc $doc -Needle "cve-feed-subscription.md" `
-Label "CVE feed cross-link"

Write-Host "Policy JSON anchors:"
Test-DocContains -Doc $policy -Needle '"schema_version"' `
-Label "schema_version" -Context "socket-posture.json"
Test-DocContains -Doc $policy -Needle "Socket Security: Pull Request Alerts" `
-Label "expected PR checks" -Context "socket-posture.json"
Test-DocContains -Doc $policy -Needle "socket-posture-check.ps1" `
-Label "verify_command" -Context "socket-posture.json"

Write-Host "Evidence path anchors:"
Test-DocContains -Doc $security -Needle "docs/ops/socket-posture.md" `
-Label "SECURITY.md -> socket-posture" -Context "SECURITY.md"
Test-DocContains -Doc $security -Needle "socket-posture-check.ps1" `
-Label "SECURITY.md SelfCheck reference" -Context "SECURITY.md"

if ($securityWf -notmatch 'socket-posture-check\.ps1') {
throw "security.yml missing socket-posture-check.ps1 SelfCheck job."
}
[void](Write-Check -Label "security.yml socket-posture SelfCheck" -Ok $true)

if ($securityWf -notmatch 'cargo-deny') {
throw "security.yml missing cargo-deny job/reference."
}
[void](Write-Check -Label "security.yml cargo-deny" -Ok $true)

if ($securityWf -notmatch 'cargo.?audit') {
throw "security.yml missing cargo-audit job/reference."
}
[void](Write-Check -Label "security.yml cargo-audit" -Ok $true)

if ($securityWf -notmatch 'gitleaks') {
throw "security.yml missing gitleaks job/reference."
}
[void](Write-Check -Label "security.yml gitleaks" -Ok $true)

if ($securityWf -notmatch 'trufflehog') {
throw "security.yml missing trufflehog job/reference."
}
[void](Write-Check -Label "security.yml trufflehog" -Ok $true)

if ($cveFeed -notmatch 'socket-posture') {
throw "cve-feed-subscription.md should cross-link socket-posture (complementary feeds)."
}
[void](Write-Check -Label "cve-feed socket cross-link" -Ok $true)

$summary = @"
## Socket posture SelfCheck

SelfCheck passed: ``docs/ops/socket-posture.md`` anchors, ``socket-posture.json``
manifest, SECURITY.md cross-link, and complementary cargo-deny / cargo-audit /
gitleaks / TruffleHog evidence. Does not claim live Socket.org install.
"@

if ($env:GITHUB_STEP_SUMMARY) {
$summary | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append -Encoding utf8
}

Write-Host "Socket posture SelfCheck passed (C06 L33; no Socket API / no org install claim)."
exit 0
32 changes: 32 additions & 0 deletions tests/socket_posture.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//! Hermetic `SelfCheck` for Socket.dev supply-chain posture (C06 L33).
//!
//! Local: `pwsh ./scripts/socket-posture-check.ps1 -SelfCheck`

use std::path::PathBuf;
use std::process::Command;

fn repo_root() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
}

#[test]
fn socket_posture_self_check_validates_policy_and_anchors() {
let script = repo_root().join("scripts/socket-posture-check.ps1");
assert!(script.is_file(), "expected socket posture script at {}", script.display());

let output = Command::new("pwsh")
.args(["-NoProfile", "-File", script.to_str().expect("utf-8 script path"), "-SelfCheck"])
.output()
.unwrap_or_else(|error| panic!("failed to spawn pwsh for SelfCheck: {error}"));

let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
output.status.success(),
"socket-posture-check.ps1 -SelfCheck failed\nstdout:\n{stdout}\nstderr:\n{stderr}"
);
assert!(
stdout.contains("Socket posture SelfCheck passed"),
"expected SelfCheck success line, got:\n{stdout}"
);
}
Loading