Files
alva/.gitea/workflows/felsokning.yml
T
Claude fbc034a280 Revisionen: C-3, C-4, M-1, M-4, M-5, M-6, m-3, m-5 och m-7 åtgärdade
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
2026-08-05 13:44:37 +00:00

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