fbc034a280
C-3 · Dataskydd genom krypto-shredding. Identifierande fält krypteras med en nyckel per ärende; radering sker genom att nyckeln förstörs. Loggen förblir intakt och hashverifierbar — det som blir oåtkomligt är identifieringen, inte protokollet över vad som kontrollerades. Ett raderat ärende visar fortfarande att lufttrycket mättes till 2,4 bar klockan 08:42, bara inte längre vems bil det gällde. Vad som inte krypteras är lika viktigt: mätvärden, observationer och kontrollresultat är verksamhetsdata. Krypteras allt raderas beviset tillsammans med personuppgiften. En raderingsbegäran gäller ett fordon, inte ett ärende — men identifieraren är krypterad och går inte att söka på. Därför ett blindat index: HMAC av den normaliserade identifieraren, samma fordon ger alltid samma värde, värdet går inte att vända tillbaka utan nyckeln. Gallringsdatum sätts vid avslut utifrån ärendetypen. Ett ärende utan datum gallras aldrig — för tidig gallring går inte att ångra. C-4 · Modellanropen kan stängas av per organisation. Flaggan bärs i token så orkestern kan neka utan databasåtkomst. Metodikmotorn fungerar ensam; en verkstad som inte kan acceptera överföringen till modelleverantören kan ändå använda produkten. M-1 · Mätvärden bär vilket mätdon som användes och när det var kalibrerat. Utan spårbart instrument nedgraderas värdet från E4 till E1 — det är teknikerns observation av en siffra, inte en mätning. Kalibreringen bedöms vid mättillfället, inte i dag. Demoärendet fick kalibrerade instrument: det ska visa den praxis produkten kräver. M-4 · Läslogg. Varje skrivning loggades redan; ingen läsning gjorde det. M-5 · Återställningstest i CI. Larmet visade att backup sker, inte att den går att återställa. Testet kontrollerar det som faktiskt brukar tappas: att append-only-triggarna följde med och fortfarande biter. M-6 · Regelpaketet verifieras mot HMAC. Ogiltig signatur spärrar avslut; saknad nyckel ger granskningsläge i stället för driftavbrott — det är så säkerhetsfunktioner blir avstängda. m-3 · EXIF-borttagningen är nu avsiktlig och låst av test. Den höll av en slump, och en ändring i stil med "bevara originalkvaliteten" hade tyst börjat publicera var kundens bil stod. m-5 · SBOM och sårbarhetsskanning i CI. m-7 · Promptversionen binds till varje svar. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
172 lines
6.5 KiB
YAML
172 lines
6.5 KiB
YAML
# Guidad Felsökning — CI på egna runners i klustret.
|
|
#
|
|
# Samma syntax som GitHub Actions men körs av Gitea Actions-runners på
|
|
# vår egen EKS. Inget externt beroende: koden, bygget och registret
|
|
# ligger i vår AWS-miljö.
|
|
#
|
|
# .github/workflows/ tillhör Semantika och rörs inte.
|
|
name: Guidad Felsökning
|
|
|
|
on:
|
|
push:
|
|
paths: ['felsokning/**', '.gitea/workflows/felsokning.yml']
|
|
pull_request:
|
|
paths: ['felsokning/**']
|
|
workflow_dispatch:
|
|
inputs:
|
|
bildtagg:
|
|
description: 'Bildtagg att driftsätta (commit-SHA från publiceringen)'
|
|
required: true
|
|
type: string
|
|
|
|
jobs:
|
|
test-och-bygg:
|
|
runs-on: felsokning
|
|
defaults:
|
|
run:
|
|
working-directory: felsokning/app
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with: { node-version: 22 }
|
|
- run: npm ci --no-audit --no-fund
|
|
- run: npx vitest run
|
|
- run: npm run typkontroll
|
|
- run: npx eslint src/felsokning src/pages/felsokning src/test --ext .ts,.tsx
|
|
- run: npm run build
|
|
|
|
tjanster:
|
|
runs-on: felsokning
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with: { node-version: 22 }
|
|
- run: npm install --no-audit --no-fund
|
|
working-directory: felsokning/services/plattform
|
|
- run: npx eslint . --ext .mjs
|
|
working-directory: felsokning/services
|
|
# Hela flödet mot riktig Postgres: organisationer, roller,
|
|
# append-only-triggern, isolering, delning, bilagor.
|
|
- run: sudo apt-get update && sudo apt-get install -y postgresql
|
|
- run: sudo bash integrationstest.sh
|
|
working-directory: felsokning/services/plattform
|
|
- run: npx swagger-cli validate felsokning/services/plattform/openapi.yaml
|
|
working-directory: .
|
|
|
|
terraform:
|
|
runs-on: felsokning
|
|
defaults:
|
|
run:
|
|
working-directory: felsokning/infra/terraform
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: hashicorp/setup-terraform@v3
|
|
with: { terraform_version: 1.9.8 }
|
|
- run: terraform fmt -check -recursive
|
|
- run: terraform init -backend=false -input=false
|
|
- run: terraform validate
|
|
|
|
# Leverantörskedjan. 53 direkta klientberoenden utan SBOM eller
|
|
# skanning var ett fynd i revisionen (QUALITET m-5): de flesta
|
|
# OEM-baslinjer för leverantörssäkerhet kräver båda.
|
|
leverantorskedja:
|
|
runs-on: felsokning
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with: { node-version: 22 }
|
|
- run: npm ci --no-audit --no-fund
|
|
working-directory: felsokning/app
|
|
# Kända sårbarheter stoppar bygget från "high" och uppåt. Lägre
|
|
# nivåer rapporteras men fäller inte — annars slutar folk läsa.
|
|
- run: npm audit --audit-level=high
|
|
working-directory: felsokning/app
|
|
- run: npm audit
|
|
working-directory: felsokning/app
|
|
continue-on-error: true
|
|
# SBOM i CycloneDX, arkiverad per bygge. Utan den går det inte att
|
|
# svara på "påverkas vi av den här sårbarheten" utan att gissa.
|
|
- run: npx --yes @cyclonedx/cyclonedx-npm@latest --output-file sbom-klient.json
|
|
working-directory: felsokning/app
|
|
- run: npm install --no-audit --no-fund && npx --yes @cyclonedx/cyclonedx-npm@latest --output-file ../sbom-plattform.json
|
|
working-directory: felsokning/services/plattform
|
|
- uses: actions/upload-artifact@v4
|
|
with:
|
|
name: sbom-${{ gitea.sha }}
|
|
path: |
|
|
felsokning/app/sbom-klient.json
|
|
felsokning/services/sbom-plattform.json
|
|
retention-days: 400
|
|
|
|
# M-5: en säkerhetskopia som aldrig återställts är en förhoppning.
|
|
# Larmet visar att backup sker, inte att den går att återställa.
|
|
aterstallning:
|
|
runs-on: felsokning
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- run: sudo apt-get update && sudo apt-get install -y postgresql
|
|
- run: sudo bash aterstallningstest.sh
|
|
working-directory: felsokning/services/plattform
|
|
|
|
# Bygger och publicerar till vårt eget ECR. Bara på main och bara när
|
|
# kontrollerna ovan gått igenom.
|
|
publicera:
|
|
needs: [test-och-bygg, tjanster, terraform, leverantorskedja, aterstallning]
|
|
if: gitea.ref == 'refs/heads/main'
|
|
runs-on: felsokning
|
|
permissions:
|
|
id-token: write
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: aws-actions/configure-aws-credentials@v4
|
|
with:
|
|
role-to-assume: ${{ vars.BYGG_ROLL_ARN }}
|
|
aws-region: ${{ vars.AWS_REGION }}
|
|
- uses: aws-actions/amazon-ecr-login@v2
|
|
id: ecr
|
|
|
|
- name: Bygg och publicera
|
|
env:
|
|
REGISTER: ${{ steps.ecr.outputs.registry }}
|
|
TAGG: ${{ gitea.sha }}
|
|
run: |
|
|
# Klientens API-adress bakas in vid bygget (Vite), så bilden är
|
|
# miljöbunden.
|
|
docker build -t "$REGISTER/guidad-felsokning-web:$TAGG" \
|
|
--build-arg VITE_PLATTFORM_URL="https://${{ vars.DOMAN }}" \
|
|
--build-arg VITE_AI_ORKESTER_URL="https://${{ vars.DOMAN }}" \
|
|
felsokning/app
|
|
# Byggkontexten är felsokning/services så båda tjänsterna når
|
|
# den delade observationsmodulen utan att den dupliceras.
|
|
docker build -t "$REGISTER/guidad-felsokning-plattform:$TAGG" \
|
|
-f felsokning/services/plattform/Dockerfile felsokning/services
|
|
docker build -t "$REGISTER/guidad-felsokning-ai-orkester:$TAGG" \
|
|
-f felsokning/services/ai-orkester/Dockerfile felsokning/services
|
|
for bild in web plattform ai-orkester; do
|
|
docker push "$REGISTER/guidad-felsokning-$bild:$TAGG"
|
|
done
|
|
|
|
# Driftsättning är ett eget, manuellt steg: en bild i registret är inte
|
|
# samma sak som en bild som kör. Rollback = kör igen med tidigare tagg.
|
|
driftsatt:
|
|
if: gitea.event_name == 'workflow_dispatch'
|
|
runs-on: felsokning
|
|
environment: produktion
|
|
permissions:
|
|
id-token: write
|
|
defaults:
|
|
run:
|
|
working-directory: felsokning/infra/terraform
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: aws-actions/configure-aws-credentials@v4
|
|
with:
|
|
role-to-assume: ${{ vars.DRIFT_ROLL_ARN }}
|
|
aws-region: ${{ vars.AWS_REGION }}
|
|
- run: aws eks update-kubeconfig --name ${{ vars.KLUSTER }}
|
|
- uses: hashicorp/setup-terraform@v3
|
|
with: { terraform_version: 1.9.8 }
|
|
- run: terraform init -input=false
|
|
- run: terraform apply -input=false -auto-approve -var bildtagg=${{ inputs.bildtagg }}
|
|
- run: terraform output karta
|