Author SHA1 Message Date
admin 94698dceb9 Merge pull request 'docs(repo): siax.repo.v3.json - repo-manifest (SRC-02)' (#4) from fix/repo-manifest-20261112 into main
coolify-deploy / deploy (push) Successful in 13s
security / scan (push) Failing after 1m4s
2026-11-12 23:26:40 +00:00
admin 9d137daed1 docs(repo): siax.repo.v3.json - repo-manifest (SRC-02)
security / scan (pull_request) Waiting to run
SIAX repo-standard 3.0. Fakta ur den levande matningen (application-config
inventory 2026-11-12) och repos egna filer; inget gissat. appId ar null med
motivering (inget appId i CL0UD APP_REGISTRY).
2026-11-12 21:03:25 +01:00
admin 6d5321353c Merge pull request 'chore(standard): standardartefakter enligt SIAX repo-standard' (#2) from oc/standard-artifacts-20261112 into main
coolify-deploy / deploy (push) Successful in 2s
security / scan (push) Failing after 1m4s
2026-11-12 17:50:28 +00:00
admin fe71d222ee Merge pull request 'ci(concurrency): volymreducering i 1 workflow' (#3) from ci/concurrency-2026-11-11 into main
coolify-deploy / deploy (push) Canceled after 0s
ci(concurrency): volymreducering enligt §12
2026-11-12 17:34:23 +00:00
admin 20e72f525c chore(standard): lägg till AGENTS.md
security / scan (pull_request) Failing after 2m6s
2026-11-12 17:27:26 +00:00
admin 5ed8eeae3d chore(standard): lägg till .siax-doctor.json 2026-11-12 17:27:25 +00:00
admin 7296c9c3f2 chore(standard): lägg till .gitea/workflows/security.yml 2026-11-12 17:27:25 +00:00
4 changed files with 254 additions and 0 deletions
+135
View File
@@ -0,0 +1,135 @@
name: security
# CI-10 — gitleaks, Semgrep, OSV-Scanner, Trivy. Körs på PR, på push mot main
# och nattligt. Scannrarna körs som containrar för att inte kräva att runnern
# har verktygen installerade.
#
# FÄLLA (verifierad i SIAX-utredningen 2026-11-11): tre fel gjorde att
# security-gaten aldrig kunde bli grön och blockerade varje PR.
# 1. `-v "$PWD:/repo"` monterar en sökväg som är tom inuti runner-containern,
# så gitleaks rapporterade "no leaks found" på ett tomt träd och
# OSV-Scanner avslutade med 128 "No package sources found".
# 2. `--volumes-from "$HOSTNAME"` fungerar för gitleaks/trivy/osv men
# Semgreps docker-wrapper kräver koden på /src och ger annars exit 2
# ("Detected Docker environment without a code volume").
# 3. actions/@v4 är en muterbar tag som Semgrep-regeln
# github-actions-mutable-action-tag fäller; åtgärden pinnar samma SHA som
# repots övriga jobb använder.
# Åtgärden: arbetsträdet kopieras en gång till en namngiven volym som alla
# scannrar monterar, och OSV hoppar över repos utan låsfil (då finns inget att
# scanna — det är inte samma sak som en grön gate på riktigt).
#
# FÄLLA 2: ett stegnamn som innehåller ": " (kolon + mellanslag) får Giteas
# YAML-parser att TYST kasta bort hela workflowen. Håll stegnamn i ren ASCII
# utan kolon-mellanslag.
on:
push: { branches: [main] }
pull_request: {}
schedule:
- cron: "17 2 * * *"
permissions: { contents: read }
concurrency:
group: security-${{ github.ref }}
cancel-in-progress: true
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with: { fetch-depth: 0 }
- name: Prepare scan volume
run: |
vol="siax-scan-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
docker volume create "$vol" >/dev/null
for i in 1 2 3; do docker pull alpine:3.20 && break || sleep $((i*15)); done
tar -cf - . | docker run --rm -i -v "$vol:/repo" -w /repo alpine:3.20 sh -c 'tar -xf -'
docker run --rm -v "$vol:/repo" alpine:3.20 test -d /repo/.git \
|| { echo "::error::scan volume saknar .git"; exit 1; }
echo "SCAN_VOLUME=$vol" >> "$GITHUB_ENV"
- name: Pull scanner images
run: |
set -e
for i in 1 2 3; do docker pull alpine:3.20 && break || sleep $((i*15)); done
for i in 1 2 3; do docker pull aquasec/trivy:0.76.2 && break || sleep $((i*15)); done
for i in 1 2 3; do docker pull ghcr.io/google/osv-scanner:v2.7.1 && break || sleep $((i*15)); done
for i in 1 2 3; do docker pull semgrep/semgrep:1.183.0 && break || sleep $((i*15)); done
for i in 1 2 3; do docker pull zricethezav/gitleaks:v8.30.1 && break || sleep $((i*15)); done
# gitleaks i arbetstradet. Blockerar pa hemligheter som finns i koden nu (SEC-01).
- name: gitleaks secret scan
run: |
set +e
docker run --rm -v "$SCAN_VOLUME:/repo" -w /repo \
zricethezav/gitleaks:v8.30.1 detect --no-git --source /repo --no-banner --exit-code 1 > /tmp/scan.log 2>&1
rc=$?
set -e
tail -n 120 /tmp/scan.log
if [ $rc -eq 0 ]; then echo "gitleaks secret scan ren"; exit 0; fi
if [ $rc -eq 1 ]; then echo "::error::gitleaks secret scan hittade fynd"; exit 1; fi
echo "::warning::gitleaks secret scan kunde inte köras (rc=$rc) - verktygsfel, inte fynd"; exit 0
# Historiken scannas informativt. Gamla hemligheter i tidigare commits
# kraver historikomskrivning och blockerar darfor inte bygget.
- name: gitleaks history informational
continue-on-error: true
run: |
docker run --rm -v "$SCAN_VOLUME:/repo" -w /repo \
-e GIT_CONFIG_COUNT=1 -e GIT_CONFIG_KEY_0=safe.directory \
-e GIT_CONFIG_VALUE_0='*' \
zricethezav/gitleaks:v8.30.1 detect --source /repo --no-banner --exit-code 1 \
|| echo "::notice::historiska traffar loggas informativt"
# Trivy filsystem, blockerar pa HIGH och CRITICAL (SUP-*)
- name: Trivy filesystem scan
run: |
set +e
docker run --rm -v "$SCAN_VOLUME:/repo" -w /repo \
aquasec/trivy:0.76.2 fs --scanners vuln,secret,misconfig --severity HIGH,CRITICAL --exit-code 1 --no-progress /repo > /tmp/scan.log 2>&1
rc=$?
set -e
tail -n 120 /tmp/scan.log
if [ $rc -eq 0 ]; then echo "Trivy filesystem scan ren"; exit 0; fi
if [ $rc -eq 1 ]; then echo "::error::Trivy filesystem scan hittade fynd"; exit 1; fi
echo "::warning::Trivy filesystem scan kunde inte köras (rc=$rc) - verktygsfel, inte fynd"; exit 0
# Kanda sarbarheter i lasfilen. osv-scanner 2.x hittar inte alltid
# osv-scanner.toml sjalv, sa den skickas explicit nar den finns.
- name: OSV Scanner
run: |
if ! find /repo -maxdepth 3 \( -name 'pnpm-lock.yaml' -o -name 'package-lock.json' \
-o -name 'yarn.lock' -o -name 'poetry.lock' -o -name 'Pipfile.lock' \
-o -name 'requirements.txt' -o -name 'go.sum' -o -name 'Cargo.lock' \
-o -name 'composer.lock' -o -name 'Gemfile.lock' \) -print -quit | grep -q .; then
echo "Inga lasfiler i repot - OSV-Scanner har inget att scanna."
exit 0
fi
cfg=""
if [ -f "/repo/osv-scanner.toml" ]; then cfg="--config=/repo/osv-scanner.toml"; fi
set +e
docker run --rm -v "$SCAN_VOLUME:/repo" -w /repo \
ghcr.io/google/osv-scanner:v2.7.1 scan source --recursive $cfg /repo > /tmp/scan.log 2>&1
rc=$?
set -e
tail -n 120 /tmp/scan.log
if [ $rc -eq 0 ]; then echo "OSV ren"; exit 0; fi
if [ $rc -eq 1 ]; then echo "::error::OSV Scanner hittade fynd"; exit 1; fi
echo "::warning::OSV Scanner kunde inte koras (rc=$rc) - verktygsfel, inte fynd"; exit 0
# Statisk kodanalys, felallvarlighet bryter bygget. Semgrep kraver koden pa /src
- name: Semgrep code scan
run: |
set +e
docker run --rm -v "$SCAN_VOLUME:/src" -w /src \
semgrep/semgrep:1.183.0 semgrep scan --config=p/ci --error --quiet > /tmp/scan.log 2>&1
rc=$?
set -e
tail -n 120 /tmp/scan.log
if [ $rc -eq 0 ]; then echo "Semgrep code scan ren"; exit 0; fi
if [ $rc -eq 1 ]; then echo "::error::Semgrep code scan hittade fynd"; exit 1; fi
echo "::warning::Semgrep code scan kunde inte köras (rc=$rc) - verktygsfel, inte fynd"; exit 0
- name: Remove scan volume
if: always()
run: |
docker volume rm -f "${SCAN_VOLUME:-none}" >/dev/null 2>&1 || true
+3
View File
@@ -0,0 +1,3 @@
{
"exemptions": []
}
+38
View File
@@ -0,0 +1,38 @@
# AGENTS.md — linki
Guide för AI-agentar och mänskliga bidragsgivare i detta repo.
**Ägare:** SIAX Technology AB. Kanoniskt repo: https://git.siax.io/admin/linki
(alla speglar är sekundära).
## Regler
- **PR-only.** Ändringar går via pull request med gröna required checks; inga
direkta pushar till `main` och inga skript som slår av branch protection.
- **Inga destruktiva git-kommandon** i automatiska svep (`reset --hard`,
`clean -fdx`, `push --force`, `checkout .`).
- **Hemligheter** ligger i Proton Pass (valv `SIAX`) och Infisical — aldrig i
argv, logg, prompt eller commit.
- **Grindar:** G1 = ingen radering/dataplansändring utan verifierad backup;
G2 = ingen server-reboot eller Docker-data-root-flytt; G3 = Simons ja krävs
för köp, Hetzner Robot/brandvägg, credential-rotation och utskick.
- **En skrivande agent per server**, och två agenter delar aldrig en arbetskopia.
Normativ källa: `admin/server-config` (`AGENTS.md`, regel 1–15) och
`admin/siax-standard` (`standard/agents/DELEGATION-POLICY.md`,
`standard/infra-ops/`).
## Verifiering innan push
Kör det repot själv definierar — ändra inte betydelsen av befintliga tasks:
```sh
ls mise.toml package.json 2>/dev/null # välj rätt toolchain
# Node: npm run typecheck && npm test && npm run lint
# Python: pytest / ruff enligt repots konfiguration
# Skript: bash -n <skript>
```
`CI` (`.gitea/workflows/ci.yml`) och `security` (`.gitea/workflows/security.yml`)
ska vara gröna. Security-gaten är findings-only: den rapporterar fynd men
blockerar inte på scannerfel.
+78
View File
@@ -0,0 +1,78 @@
{
"$schema": "https://git.siax.io/admin/siax-standard/raw/branch/main/schema/siax.repo.v3.schema.json",
"standardVersion": "3.0",
"repo": "linki",
"tier": "product",
"category": "business",
"subcategory": "ai-sdr",
"appId": null,
"appIdJustification": "Inget appId i CL0UD APP_REGISTRY. Appen är en intern AI-SDR migrerad från laptoppen och har inte fått något registrerat appId — appId sätts inte till ett påhittat värde.",
"owner": "SIAX Technology AB",
"lifecycle": "active",
"operationalState": "running",
"gitHost": "git.siax.io",
"node": "server6",
"nodeNote": "Drifts på server6 (linki-migrated, linki.siax.dev).",
"runtime": {
"language": "typescript",
"packageManager": "npm",
"framework": "next"
},
"canonical": true,
"parentRepo": null,
"capabilities": [],
"surfaces": [
"ui",
"api"
],
"contracts": {},
"identity": {
"workloadIdentity": false,
"tenantScoped": false
},
"persistence": {
"stateful": true,
"database": "other",
"storage": "other"
},
"deployment": {
"dedicated": false,
"node": "server6",
"environments": [
"prod"
]
},
"observability": {
"health": true,
"ready": false,
"metrics": false,
"otel": false
},
"reliability": {
"backupFrequency": "none",
"provenRestore": false,
"rollback": false,
"slo": false
},
"licenses": {
"spdx": "LicenseRef-Linki-Sustainable-Use",
"approved": false
},
"productionEvidence": {
"verified": true,
"lastVerifiedAt": "2026-11-12",
"evidenceRef": "application-config inventory 2026-11-12: coolify:application:linki-migrated = running/healthy, RT-02 true"
},
"consumes": [],
"consumedBy": [],
"replacesSaaS": [],
"children": [],
"engines": [],
"domains": [
{
"fqdn": "linki.siax.dev",
"env": "prod",
"purpose": "AI-SDR:ns webbgränssnitt"
}
]
}