一键导入
threat-model
STRIDE-A trusselmodellering for Nais-mikrotjenester — dataflyt, tillitsgrenser og risikovurdering
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
STRIDE-A trusselmodellering for Nais-mikrotjenester — dataflyt, tillitsgrenser og risikovurdering
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Generer conventional commit-meldinger med Nav-relevante scopes og breaking change-format
Expert builder for the Aksel design system (Nav / @navikt) React components, design tokens, layout primitives, theming (light/dark), icons, CSS, the Tailwind preset, version migrations, and Figma-to-code. Trigger on any frontend UI task that mentions Aksel, Nav/Navikt, "designsystemet", or @navikt/ds-* / @navikt/aksel-* packages — or that asks to add, create, build, or refactor a component (button, input, modal, table, alert, card, form) or layout, or to implement a design from Figma (a pasted figma.com/design/...?node-id link, "implement this design", "build this from Figma", design-to-code). Strong signals "using/with aksel", "@navikt/ds-react", "design system", a pasted figma.com link. If the work is frontend UI and there is any Aksel signal, invoke this skill unless the user explicitly opts out.
Integrer og konfigurer Nav Dekoratøren – felles header og footer for nav.no-applikasjoner. Bruk når et team skal ta i bruk Dekoratøren, oppdatere konfigurasjon, legge til breadcrumbs/språkvelger/analytics, håndtere samtykke (ekomloven), CSP eller feilsøke integrasjon mot dekoratøren.
Lag responsive layouts med Aksel Design System (v8+) - spacing tokens, layout primitives (Box, HStack, VStack, HGrid, Page, Bleed) og ResponsiveProp
Generer og kjør Playwright E2E-tester for webapplikasjoner med page objects, auth fixtures og tilgjengelighetstester
Kompakt output-stil som kutter fyllord og beholder teknisk substans — spar output-tokens uten å miste nøyaktighet.
| name | threat-model |
| description | STRIDE-A trusselmodellering for Nais-mikrotjenester — dataflyt, tillitsgrenser og risikovurdering |
| license | MIT |
| metadata | {"domain":"auth","tags":"threat-modeling stride security nais architecture"} |
Systematic threat identification for NAIS microservices using the STRIDE-A methodology. Produces a data flow diagram, structured threats table, prioritized mitigations, and residual risk summary.
Start by answering these questions to establish the threat model boundary:
Map the system using these element types:
| Symbol | Element | Example |
|---|---|---|
[External Entity] | User or external system | [Citizen Browser], [Partner API] |
(Process) | Your service or component | (dp-soknad), (dp-behandling) |
{Data Store} | Database, topic, bucket | {PostgreSQL}, {kafka: dp.soknad.v1}, {GCS Bucket} |
--> | Data flow | [User] --> (API) |
== boundary == | Trust boundary | == Internet/Ingress == |
[Citizen Browser]
|
| HTTPS (ID-porten login)
|
== Internet → Ingress (Wonderwall) ===========================
|
| Authorization header (JWT)
|
(dp-soknad-frontend)
|
| TokenX token exchange
|
== Frontend → Backend (TokenX validated) =====================
|
| REST/JSON + Bearer token
|
(dp-soknad-api)
|
|--- REST (Azure AD M2M) ---> (dp-behandling)
|
|--- Kafka produce ---------> {kafka: dp.soknad.v1}
| |
| | Kafka consume
| v
| (dp-mottak)
|
|--- SQL (Nais credentials) -> {PostgreSQL: dp-soknad-db}
|
|--- HTTPS (egress) --------> [External: Altinn API]
|
== Application → Database (mTLS, connection pooling) =========
== Application → Kafka (mTLS, schema registry) ===============
== Application → External (egress policy, HTTPS) =============
Identify these trust boundaries in every Nav threat model:
| Boundary | Transition | Security Mechanism |
|---|---|---|
| Internet → Ingress | External user to Nais | Wonderwall + ID-porten / Azure AD |
| Ingress → Application | Sidecar to app container | Token validation (JWT claims) |
| Application → Application | Service-to-service | TokenX token exchange / Azure AD M2M |
| Application → Kafka | App to message broker | mTLS (Nais-managed certs), schema validation |
| Application → Database | App to PostgreSQL | Nais-injected credentials, connection pooling |
| Application → External API | App to outside Nais | Egress policy, mutual TLS, API keys |
| GCP → On-prem | Cloud to legacy systems | NAV VPN / Private Service Connect |
Analyze each element and data flow against all seven threat categories.
Can an attacker impersonate a legitimate user or service?
Nav-specific threats:
azp (authorized party) validation on M2M tokenssub claim in test environments leaking to prodiss and aud validationDetection patterns:
// ✅ Correct — validate azp against pre-authorized apps
fun validateAzp(token: JWTClaimsSet) {
val azp = token.getStringClaim("azp")
val preAuthorized = System.getenv("AZURE_APP_PRE_AUTHORIZED_APPS")
require(azp in parsePreAuthorizedApps(preAuthorized)) {
"Unauthorized client: $azp"
}
}
// ❌ Vulnerable — only checks signature, not authorized party
fun validateToken(token: JWTClaimsSet) {
require(token.expirationTime.after(Date())) { "Token expired" }
// Missing: azp, iss, aud validation
}
Can an attacker modify data in transit or at rest?
Nav-specific threats:
Detection patterns:
// ✅ Correct — validate and sanitize input
data class SoknadRequest(
@field:Pattern(regexp = "^[0-9]{11}$") val fnr: String,
@field:Size(max = 500) val beskrivelse: String,
@field:NotNull val soknadsdato: LocalDate,
)
// ❌ Vulnerable — raw Map, no validation
@PostMapping("/api/soknad")
fun create(@RequestBody body: Map<String, Any>): ResponseEntity<*> {
repository.save(body) // no validation, no type safety
}
Can an actor deny performing an action?
Nav-specific threats:
Detection patterns:
// ✅ Correct — structured audit log with actor, action, resource
logger.info(
"Vedtak fattet",
kv("action", "vedtak.opprettet"),
kv("actor", saksbehandler.navIdent),
kv("vedtakId", vedtak.id),
kv("sakId", sak.id),
kv("correlationId", MDC.get("x-correlation-id")),
// Never log PII — fnr, name, address
)
// ❌ Insufficient — no actor, no correlation, PII leaked
logger.info("Vedtak opprettet for bruker ${bruker.fnr}")
Can an attacker access data they should not see?
Nav-specific threats:
Detection patterns:
// ✅ Correct — return only what the consumer needs
data class VedtakResponse(
val vedtakId: UUID,
val status: String,
val dato: LocalDate,
// No FNR, no internal IDs, no sensitive details
)
// ❌ Vulnerable — returns entire entity including PII
@GetMapping("/api/vedtak/{id}")
fun getVedtak(@PathVariable id: UUID) = vedtakRepository.findById(id)
# ✅ Correct — app-specific Kafka ACL
spec:
kafka:
pool: nav-prod
streams: true
topics:
- topic: dp.soknad.v1
access: readwrite # only this app
# ❌ Vulnerable — overly broad topic access
Can an attacker degrade or disable the service?
Nav-specific threats:
Detection patterns:
# ✅ Correct — Nais resource limits and liveness probes
spec:
resources:
limits:
memory: 512Mi
requests:
cpu: 50m
memory: 256Mi
liveness:
path: /isalive
initialDelay: 10
timeout: 1
periodSeconds: 5
readiness:
path: /isready
initialDelay: 10
timeout: 1
// ✅ Correct — bounded query with pagination
fun findByIdent(ident: String, page: Int, size: Int = 50): List<Vedtak> {
require(size <= 100) { "Page size too large" }
return jdbcTemplate.query(
"SELECT * FROM vedtak WHERE ident = ? ORDER BY dato DESC LIMIT ? OFFSET ?",
vedtakMapper, ident, size, page * size
)
}
// ❌ Vulnerable — unbounded query
fun findByIdent(ident: String) = jdbcTemplate.query(
"SELECT * FROM vedtak WHERE ident = ?", vedtakMapper, ident
)
Can an attacker gain access they should not have?
Nav-specific threats:
Detection patterns:
// ✅ Correct — resource-level ownership check
@GetMapping("/api/vedtak/{id}")
fun getVedtak(@PathVariable id: UUID): ResponseEntity<VedtakDTO> {
val bruker = hentInnloggetBruker()
val vedtak = vedtakService.findById(id)
?: return ResponseEntity.notFound().build()
if (vedtak.brukerId != bruker.id) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build()
}
return ResponseEntity.ok(vedtak.toDTO())
}
// ❌ Vulnerable — IDOR, no ownership check
@GetMapping("/api/vedtak/{id}")
fun getVedtak(@PathVariable id: UUID) =
ResponseEntity.ok(vedtakService.findById(id))
Can an attacker misuse legitimate functionality?
Nav-specific threats:
Detection patterns:
// ✅ Correct — idempotency key prevents duplicates
@PostMapping("/api/soknad")
fun submitSoknad(
@RequestHeader("Idempotency-Key") idempotencyKey: String,
@RequestBody request: SoknadRequest,
): ResponseEntity<SoknadResponse> {
val existing = soknadService.findByIdempotencyKey(idempotencyKey)
if (existing != null) {
return ResponseEntity.ok(existing.toResponse())
}
val soknad = soknadService.create(request, idempotencyKey)
return ResponseEntity.status(HttpStatus.CREATED).body(soknad.toResponse())
}
// ❌ Vulnerable — no idempotency, allows duplicate submissions
@PostMapping("/api/soknad")
fun submitSoknad(@RequestBody request: SoknadRequest) =
ResponseEntity.ok(soknadService.create(request))
Rate each identified threat using severity levels:
| Severity | Description | Criteria |
|---|---|---|
| Critical | Immediate exploitation risk | PII breach, auth bypass, data corruption at scale |
| High | Significant impact if exploited | IDOR, missing access control, unvalidated input on sensitive endpoints |
| Medium | Moderate impact, requires conditions | Missing rate limiting, verbose error messages, broad Kafka ACLs |
| Low | Minimal impact or unlikely | Missing HSTS headers, informational log leakage |
Document every identified threat in this format:
| ID | Element | STRIDE | Threat | Severity | Mitigation | Status |
|----|---------|--------|--------|----------|------------|--------|
| T1 | API Gateway | S | Forged JWT bypasses auth | Critical | Validate `iss`, `aud`, `exp`, `azp` claims | ☐ |
| T2 | dp-soknad-api | T | Unvalidated request body | High | Add `@Valid` + request DTO with constraints | ☐ |
| T3 | Kafka producer | T | Unsigned messages | Medium | Enable schema registry validation | ☐ |
| T4 | dp-soknad-api | R | No audit trail for vedtak | High | Add structured audit logging with actor + correlationId | ☐ |
| T5 | API response | I | PII in error responses | High | Use ProblemDetail, strip stack traces in prod | ☐ |
| T6 | PostgreSQL | I | Overly broad query results | Medium | Return DTOs with only required fields | ☐ |
| T7 | Public endpoint | D | No rate limiting | Medium | Add rate limiter (token bucket, 100 req/min) | ☐ |
| T8 | GET /vedtak/{id} | E | IDOR — no ownership check | Critical | Add resource-level access control | ☐ |
| T9 | POST /soknad | A | Duplicate submissions | Medium | Implement idempotency key pattern | ☐ |
Status legend: ☐ Open, ☑ Mitigated, ◐ In Progress, ⊘ Accepted Risk
Map threats to concrete Nav platform mitigations. Six areas to cover:
iss, aud, exp, azp)accessPolicy inbound/outbound allow-lists, egress restrictionsSee references/nav-mitigations.md for code examples of each mitigation area.
The completed threat model should include these four deliverables:
Text-based DFD showing all elements, data flows, and trust boundaries (see Step 2).
Complete table with all identified threats across STRIDE-A categories (see Step 4).
Ordered list of mitigations, grouped by priority:
### P0 — Fix Immediately
- [ ] T1: Validate JWT claims (iss, aud, azp) on all protected endpoints
- [ ] T8: Add resource-level ownership check on GET /vedtak/{id}
### P1 — Fix Before Launch
- [ ] T2: Add request validation DTOs with Bean Validation
- [ ] T4: Implement structured audit logging for vedtak operations
- [ ] T5: Strip stack traces from error responses in prod
### P2 — Fix Soon
- [ ] T7: Add rate limiting on public endpoints
- [ ] T9: Implement idempotency key pattern for POST /soknad
- [ ] T3: Enable Kafka schema registry validation
Document risks that are accepted, transferred, or cannot be fully mitigated:
| Risk | Severity | Rationale | Owner | Review Date |
|------|----------|-----------|-------|-------------|
| Kafka message replay | Low | mTLS + consumer idempotency makes replay difficult | Team Dagpenger | 2025-Q3 |
| GCS bucket misconfiguration | Medium | Nais manages IAM; manual audit quarterly | Platform team | 2025-Q2 |
| Resource | Use For |
|---|---|
@security-champion-agent | Security architecture, compliance, Nav security culture |
security-review skill | Pre-commit scanning (trivy, zizmor, secrets) |
@auth-agent | JWT validation, TokenX, ID-porten implementation |
@nais-agent | accessPolicy, network policy, secrets management |
nav-architecture-review skill | Architecture Decision Records with security perspective |
| sikkerhet.nav.no | Nav Golden Path, authoritative security guidance |