gaia-framework 1.65.1 → 1.83.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/gaia-create-stakeholder.md +20 -0
- package/.claude/commands/gaia-test-gap-analysis.md +17 -0
- package/CLAUDE.md +102 -1
- package/README.md +2 -2
- package/_gaia/_config/global.yaml +5 -1
- package/_gaia/_config/lifecycle-sequence.yaml +20 -0
- package/_gaia/_config/skill-manifest.csv +2 -0
- package/_gaia/_config/workflow-manifest.csv +3 -1
- package/_gaia/core/engine/workflow.xml +11 -1
- package/_gaia/core/protocols/review-gate-check.xml +29 -1
- package/_gaia/core/workflows/party-mode/steps/step-01-agent-loading.md +60 -9
- package/_gaia/creative/workflows/problem-solving/checklist.md +64 -14
- package/_gaia/creative/workflows/problem-solving/instructions.xml +367 -22
- package/_gaia/creative/workflows/problem-solving/workflow.yaml +31 -1
- package/_gaia/dev/agents/_base-dev.md +7 -1
- package/_gaia/dev/skills/_skill-index.yaml +9 -0
- package/_gaia/dev/skills/figma-integration.md +296 -0
- package/_gaia/lifecycle/knowledge/brownfield/config-contradiction-scan.md +137 -0
- package/_gaia/lifecycle/knowledge/brownfield/dead-code-scan.md +179 -0
- package/_gaia/lifecycle/knowledge/brownfield/test-execution-scan.md +209 -0
- package/_gaia/lifecycle/skills/document-rulesets.md +91 -6
- package/_gaia/lifecycle/templates/brownfield-scan-doc-code-prompt.md +219 -0
- package/_gaia/lifecycle/templates/brownfield-scan-hardcoded-prompt.md +169 -0
- package/_gaia/lifecycle/templates/brownfield-scan-integration-seam-prompt.md +127 -0
- package/_gaia/lifecycle/templates/brownfield-scan-runtime-behavior-prompt.md +141 -0
- package/_gaia/lifecycle/templates/brownfield-scan-security-prompt.md +440 -0
- package/_gaia/lifecycle/templates/gap-entry-schema.md +282 -0
- package/_gaia/lifecycle/templates/infra-prd-template.md +356 -0
- package/_gaia/lifecycle/templates/platform-prd-template.md +431 -0
- package/_gaia/lifecycle/templates/prd-template.md +70 -0
- package/_gaia/lifecycle/templates/story-template.md +22 -1
- package/_gaia/lifecycle/workflows/2-planning/create-ux-design/instructions.xml +52 -3
- package/_gaia/lifecycle/workflows/4-implementation/add-feature/checklist.md +1 -1
- package/_gaia/lifecycle/workflows/4-implementation/add-feature/instructions.xml +2 -3
- package/_gaia/lifecycle/workflows/4-implementation/add-stories/checklist.md +5 -0
- package/_gaia/lifecycle/workflows/4-implementation/add-stories/instructions.xml +73 -1
- package/_gaia/lifecycle/workflows/4-implementation/create-stakeholder/checklist.md +25 -0
- package/_gaia/lifecycle/workflows/4-implementation/create-stakeholder/instructions.xml +79 -0
- package/_gaia/lifecycle/workflows/4-implementation/create-stakeholder/workflow.yaml +22 -0
- package/_gaia/lifecycle/workflows/4-implementation/create-story/instructions.xml +11 -1
- package/_gaia/lifecycle/workflows/4-implementation/retrospective/instructions.xml +21 -1
- package/_gaia/lifecycle/workflows/4-implementation/retrospective/workflow.yaml +1 -1
- package/_gaia/lifecycle/workflows/4-implementation/validate-story/instructions.xml +11 -0
- package/_gaia/lifecycle/workflows/anytime/brownfield-onboarding/checklist.md +12 -0
- package/_gaia/lifecycle/workflows/anytime/brownfield-onboarding/instructions.xml +248 -4
- package/_gaia/lifecycle/workflows/anytime/brownfield-onboarding/workflow.yaml +1 -0
- package/_gaia/testing/workflows/test-gap-analysis/checklist.md +8 -0
- package/_gaia/testing/workflows/test-gap-analysis/instructions.xml +53 -0
- package/_gaia/testing/workflows/test-gap-analysis/workflow.yaml +38 -0
- package/bin/gaia-framework.js +44 -8
- package/bin/helpers/derive-bump-label.js +41 -0
- package/bin/helpers/validate-bump-labels.js +38 -0
- package/gaia-install.sh +96 -21
- package/package.json +1 -1
- package/_gaia/_memory/tier2-results/.gitkeep +0 -0
- package/_gaia/_memory/tier2-results/checkpoint-resume-2026-03-24.yaml +0 -6
- package/_gaia/_memory/tier2-results/engine-scenarios-2026-03-22.yaml +0 -14
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
# Security Endpoint Audit Scanner — Subagent Prompt
|
|
2
|
+
|
|
3
|
+
> Brownfield deep analysis scan subagent. Detects security gaps in API endpoints and infrastructure security configurations.
|
|
4
|
+
> Reference: Architecture ADR-021, Section 10.15.2, Section 10.15.5, ADR-022 §10.16.5
|
|
5
|
+
> Infra-awareness: E12-S6 — applies infra-specific patterns when project_type is infrastructure or platform.
|
|
6
|
+
> Non-REST protocols: E11-S17 — GraphQL and gRPC endpoint detection and security gap scanning.
|
|
7
|
+
|
|
8
|
+
## Objective
|
|
9
|
+
|
|
10
|
+
Scan the codebase at `{project-path}` to catalog all API endpoints and infrastructure security configurations, and identify security gaps.
|
|
11
|
+
|
|
12
|
+
**Input variables:**
|
|
13
|
+
- `{tech_stack}` — Detected technology stack from Step 1 discovery
|
|
14
|
+
- `{project-path}` — Absolute path to the project source code directory
|
|
15
|
+
- `{project_type}` — Project type: `application`, `infrastructure`, or `platform`
|
|
16
|
+
|
|
17
|
+
**Output format:** Follow the gap entry schema at `{project-root}/_gaia/lifecycle/templates/gap-entry-schema.md` exactly.
|
|
18
|
+
|
|
19
|
+
## Phase 1: Endpoint Discovery (Application Patterns)
|
|
20
|
+
|
|
21
|
+
Catalog all API endpoints. For each endpoint, record: route path, HTTP method, authentication, authorization, handler function.
|
|
22
|
+
|
|
23
|
+
### Stack-Aware Endpoint Discovery Patterns
|
|
24
|
+
|
|
25
|
+
Apply framework-specific patterns based on {tech_stack}:
|
|
26
|
+
|
|
27
|
+
#### Java/Spring
|
|
28
|
+
- `@GetMapping`, `@PostMapping`, `@PutMapping`, `@DeleteMapping`, `@PatchMapping`
|
|
29
|
+
- `@RequestMapping(method = RequestMethod.GET)`
|
|
30
|
+
- `RouterFunction<ServerResponse>` (Spring WebFlux)
|
|
31
|
+
- `@RestController` class-level `@RequestMapping`
|
|
32
|
+
|
|
33
|
+
#### Node/Express
|
|
34
|
+
- `app.get()`, `app.post()`, `app.put()`, `app.delete()`, `app.patch()`
|
|
35
|
+
- `router.get()`, `router.post()`, `router.put()`, `router.delete()`
|
|
36
|
+
- `app.route().get().post()`
|
|
37
|
+
- `app.all()`
|
|
38
|
+
|
|
39
|
+
#### Python/Django
|
|
40
|
+
- `path()`, `re_path()` in `urls.py`
|
|
41
|
+
- `@api_view(['GET', 'POST'])`
|
|
42
|
+
- `class XxxViewSet(viewsets.ModelViewSet)`
|
|
43
|
+
- `class XxxView(APIView)`
|
|
44
|
+
|
|
45
|
+
#### Go/Gin
|
|
46
|
+
- `r.GET()`, `r.POST()`, `r.PUT()`, `r.DELETE()`, `r.PATCH()`
|
|
47
|
+
- `group.GET()`, `group.POST()`
|
|
48
|
+
- `http.HandleFunc()`, `http.Handle()`
|
|
49
|
+
- `mux.HandleFunc()`, `mux.Handle()`
|
|
50
|
+
|
|
51
|
+
### Graceful Exit — No API Endpoints
|
|
52
|
+
|
|
53
|
+
If no API endpoints are detected, output a summary note and zero gap entries for the application phase.
|
|
54
|
+
|
|
55
|
+
## Phase 1b: GraphQL Endpoint Discovery
|
|
56
|
+
|
|
57
|
+
Catalog all GraphQL endpoints. For each endpoint, record: operation type (query/mutation/subscription), resolver function, authentication directives, authorization checks.
|
|
58
|
+
|
|
59
|
+
### Schema-First Detection Patterns
|
|
60
|
+
|
|
61
|
+
- `.graphql` and `.gql` schema files
|
|
62
|
+
- `type Query { ... }` and `type Mutation { ... }` blocks in schema files
|
|
63
|
+
- `typeDefs` variable definitions in JS/TS files (template literals with SDL)
|
|
64
|
+
|
|
65
|
+
### Code-First Detection Patterns
|
|
66
|
+
|
|
67
|
+
- `@Resolver()` decorators (NestJS, TypeGraphQL)
|
|
68
|
+
- `@Query()` and `@Mutation()` decorators
|
|
69
|
+
- `resolvers` objects exported from modules
|
|
70
|
+
- Python class-based resolvers (Strawberry `@strawberry.type`, Ariadne `@query_type.field`)
|
|
71
|
+
- Go resolver structs (gqlgen `resolver.go` files)
|
|
72
|
+
|
|
73
|
+
### GraphQL Framework Variants
|
|
74
|
+
|
|
75
|
+
Apply framework-specific patterns based on detected GraphQL library:
|
|
76
|
+
|
|
77
|
+
| Framework | Language | Detection Pattern |
|
|
78
|
+
|---|---|---|
|
|
79
|
+
| Apollo Server | Node/TS | `ApolloServer`, `@apollo/server`, Apollo plugins |
|
|
80
|
+
| GraphQL Yoga | Node/TS | `createYoga`, `@graphql-yoga/node` |
|
|
81
|
+
| Mercurius | Node/TS (Fastify) | `mercurius`, `app.graphql` |
|
|
82
|
+
| Strawberry | Python | `strawberry.Schema`, `@strawberry.type` |
|
|
83
|
+
| gqlgen | Go | `gqlgen.yml`, `generated.go`, resolver structs |
|
|
84
|
+
| Ariadne | Python | `ariadne`, `make_executable_schema` |
|
|
85
|
+
| NestJS GraphQL | Node/TS | `@nestjs/graphql`, `@Resolver()`, `@Query()`, `@Mutation()` |
|
|
86
|
+
|
|
87
|
+
### GraphQL Middleware Chain Detection
|
|
88
|
+
|
|
89
|
+
- `graphql-shield` rule trees (`const permissions = shield({ ... })`)
|
|
90
|
+
- `@UseGuards(AuthGuard)` decorators (NestJS)
|
|
91
|
+
- Apollo Server plugins (`ApolloServerPlugin` implementing `requestDidStart`)
|
|
92
|
+
- Yoga plugins (`useAuth`, custom `envelop` plugins)
|
|
93
|
+
- Custom context resolvers setting `context.user` from auth headers
|
|
94
|
+
|
|
95
|
+
### Graceful Exit — No GraphQL Endpoints
|
|
96
|
+
|
|
97
|
+
If no GraphQL schema files, resolver definitions, or GraphQL framework imports are detected, skip Phase 1b and Phase 2b entirely. Output a summary note and zero gap entries for GraphQL.
|
|
98
|
+
|
|
99
|
+
## Phase 1c: gRPC Endpoint Discovery
|
|
100
|
+
|
|
101
|
+
Catalog all gRPC endpoints. For each endpoint, record: service name, RPC method name, request/response message types, streaming type (unary/server/client/bidirectional), interceptor chain.
|
|
102
|
+
|
|
103
|
+
### Proto Service Parsing
|
|
104
|
+
|
|
105
|
+
- `.proto` files with `service` blocks defining `rpc` methods
|
|
106
|
+
- `stream` annotations on request or response types (server streaming, client streaming, bidirectional streaming)
|
|
107
|
+
- `package` declarations for service namespace
|
|
108
|
+
|
|
109
|
+
### Server Interceptor Detection
|
|
110
|
+
|
|
111
|
+
| Language | Interceptor Pattern |
|
|
112
|
+
|---|---|
|
|
113
|
+
| Java | `ServerInterceptor` interface, `@GrpcService` (Spring gRPC), interceptor registry |
|
|
114
|
+
| Go | `grpc.UnaryInterceptor()`, `grpc.StreamInterceptor()`, `grpc.ChainUnaryInterceptor()` |
|
|
115
|
+
| Python | `grpc.server_interceptor`, `intercept_service()` |
|
|
116
|
+
| Node/TS | `addService()` calls, `@GrpcMethod` decorators (NestJS), `grpc-js` server options |
|
|
117
|
+
|
|
118
|
+
### gRPC Middleware Chain Detection
|
|
119
|
+
|
|
120
|
+
- Interceptor chains in server setup (ordered middleware)
|
|
121
|
+
- `@GrpcMethod` decorators with guard annotations (NestJS)
|
|
122
|
+
- Metadata extractors for authentication tokens
|
|
123
|
+
- Health check service registration (`grpc.health.v1`)
|
|
124
|
+
|
|
125
|
+
### Graceful Exit — No gRPC Endpoints
|
|
126
|
+
|
|
127
|
+
If no `.proto` files, gRPC server setup, or gRPC framework imports are detected, skip Phase 1c and Phase 2c entirely. Output a summary note and zero gap entries for gRPC.
|
|
128
|
+
|
|
129
|
+
## Phase 1d: Mixed-Protocol Detection
|
|
130
|
+
|
|
131
|
+
A single codebase may expose REST + GraphQL + gRPC endpoints simultaneously. When multiple protocols are detected:
|
|
132
|
+
|
|
133
|
+
1. Scan all three protocols independently
|
|
134
|
+
2. Identify shared authentication middleware (e.g., a JWT validator used by both Express routes and Apollo context)
|
|
135
|
+
3. Do not double-count shared middleware as separate gaps — if auth middleware covers both REST and GraphQL, count it once
|
|
136
|
+
4. Note in findings when multiple protocols share infrastructure
|
|
137
|
+
|
|
138
|
+
## Phase 2: Security Gap Detection — Application Rules
|
|
139
|
+
|
|
140
|
+
### 1. Missing Authentication Middleware (AC3a)
|
|
141
|
+
|
|
142
|
+
Detect endpoints with no authentication middleware. Mutating endpoints (POST, PUT, PATCH, DELETE) missing auth are `critical`. Read endpoints (GET) missing auth that return non-public data are `high`.
|
|
143
|
+
|
|
144
|
+
### 2. IDOR Vulnerability Detection (AC3b)
|
|
145
|
+
|
|
146
|
+
Detect endpoints where path parameters reference resources without ownership validation. IDOR vulnerabilities are `critical` severity.
|
|
147
|
+
|
|
148
|
+
### 3. Rate Limiting Gap Detection (AC3c)
|
|
149
|
+
|
|
150
|
+
Detect endpoints without rate limiting at the application level. Missing rate limiting is `high` severity.
|
|
151
|
+
|
|
152
|
+
**Note:** Reverse proxy or API gateway rate limiting is not visible to static code analysis. Verify infrastructure-level rate limiting separately.
|
|
153
|
+
|
|
154
|
+
### 4. Sensitive Data Exposure Detection (AC3d)
|
|
155
|
+
|
|
156
|
+
Detect endpoints whose response objects contain fields that should be filtered:
|
|
157
|
+
- `password`, `password_hash`, `hashed_password`
|
|
158
|
+
- `token`, `access_token`, `refresh_token`, `api_key`, `secret`
|
|
159
|
+
- `ssn`, `social_security`, `national_id`
|
|
160
|
+
- `credit_card`, `card_number`, `cvv`, `expiry`
|
|
161
|
+
- Any field matching patterns: `*_secret`, `*_key`, `*_token`
|
|
162
|
+
|
|
163
|
+
Sensitive data exposure is `high` severity.
|
|
164
|
+
|
|
165
|
+
### 5. Missing Input Validation on Mutating Endpoints (AC3e)
|
|
166
|
+
|
|
167
|
+
Detect POST/PUT/PATCH/DELETE endpoints that accept a request body but have no input validation. Missing input validation is `high` severity.
|
|
168
|
+
|
|
169
|
+
## Phase 2b: GraphQL Security Gap Detection
|
|
170
|
+
|
|
171
|
+
### 1. Queries/Mutations Missing Auth Directives
|
|
172
|
+
|
|
173
|
+
Detect GraphQL operations missing authentication. Look for:
|
|
174
|
+
- Resolvers without `@auth`, `@authenticated`, `@HasPermission`, or `@UseGuards(AuthGuard)` directives
|
|
175
|
+
- Schema types without `@auth` directive when other types have it (inconsistent protection)
|
|
176
|
+
- Mutation resolvers with no authorization checks are `critical` severity
|
|
177
|
+
- Query resolvers returning non-public data without auth are `high` severity
|
|
178
|
+
|
|
179
|
+
### 2. Introspection Enabled in Production
|
|
180
|
+
|
|
181
|
+
Detect GraphQL introspection configuration that may leak schema in production:
|
|
182
|
+
- `introspection: true` in Apollo Server config without `NODE_ENV` conditional
|
|
183
|
+
- Missing introspection disable in production configuration
|
|
184
|
+
- Yoga/Mercurius default introspection without explicit disable
|
|
185
|
+
|
|
186
|
+
Introspection in production is `medium` severity.
|
|
187
|
+
|
|
188
|
+
### 3. Mutations Without Authorization Checks
|
|
189
|
+
|
|
190
|
+
Detect mutation resolvers that lack authorization logic:
|
|
191
|
+
- Mutation handlers with no permission checks, guard decorators, or authorization middleware
|
|
192
|
+
- `graphql-shield` rules that allow mutations without role checks
|
|
193
|
+
- NestJS mutations without `@UseGuards()` when other mutations have guards
|
|
194
|
+
|
|
195
|
+
Missing mutation authorization is `critical` severity.
|
|
196
|
+
|
|
197
|
+
### 4. Field-Level Authorization Gaps
|
|
198
|
+
|
|
199
|
+
Detect sensitive fields exposed without field-level auth controls:
|
|
200
|
+
- Fields named `email`, `password`, `ssn`, `token`, `secret`, `creditCard` without `@Authorized` or field-level resolvers
|
|
201
|
+
- Resolver types exposing sensitive nested objects without per-field permission checks
|
|
202
|
+
- User types exposing admin-only fields to all authenticated users
|
|
203
|
+
|
|
204
|
+
Field-level authorization gaps are `high` severity.
|
|
205
|
+
|
|
206
|
+
### 5. GraphQL Federation and Schema Stitching
|
|
207
|
+
|
|
208
|
+
When Apollo Federation or schema stitching is detected:
|
|
209
|
+
- Note gateway-level auth that may mask per-service gaps
|
|
210
|
+
- Flag subgraph services that rely solely on gateway auth without their own validation
|
|
211
|
+
- Detect `@external` fields without authorization in the owning subgraph
|
|
212
|
+
|
|
213
|
+
Federation auth gaps are `medium` severity with a note about gateway-level coverage.
|
|
214
|
+
|
|
215
|
+
## Phase 2c: gRPC Security Gap Detection
|
|
216
|
+
|
|
217
|
+
### 1. Services Missing Auth Interceptors
|
|
218
|
+
|
|
219
|
+
Detect gRPC server setup without authentication interceptors:
|
|
220
|
+
- Server initialization without `AuthInterceptor` or equivalent in the interceptor chain
|
|
221
|
+
- Services registered via `addService` with no auth middleware applied
|
|
222
|
+
- Spring gRPC services without `@GrpcService` security configuration
|
|
223
|
+
|
|
224
|
+
Missing auth interceptor is `critical` severity.
|
|
225
|
+
|
|
226
|
+
### 2. Unary RPCs Without Authorization Metadata
|
|
227
|
+
|
|
228
|
+
Detect unary RPC methods that do not validate authorization metadata:
|
|
229
|
+
- `rpc` method handlers that do not extract or validate `metadata` authorization headers
|
|
230
|
+
- Handler functions that skip token/credential validation from gRPC metadata
|
|
231
|
+
- Methods that do not check caller identity or roles from request context
|
|
232
|
+
|
|
233
|
+
Missing unary authorization is `high` severity.
|
|
234
|
+
|
|
235
|
+
### 3. Streaming RPCs Without Per-Message Auth
|
|
236
|
+
|
|
237
|
+
Detect bidirectional and server streaming RPCs without per-message authentication:
|
|
238
|
+
- Stream handlers that authenticate only at connection start but not per-message
|
|
239
|
+
- Bidirectional streams without per-message auth validation
|
|
240
|
+
- Server streaming RPCs that do not re-validate authorization on long-lived connections
|
|
241
|
+
|
|
242
|
+
Missing stream auth is `high` severity.
|
|
243
|
+
|
|
244
|
+
### 4. TLS Configuration Gaps
|
|
245
|
+
|
|
246
|
+
Detect insecure gRPC transport configuration:
|
|
247
|
+
- `grpc.insecure_port` usage in non-development configuration
|
|
248
|
+
- `ServerCredentials.createInsecure()` in production server setup
|
|
249
|
+
- Missing TLS certificate configuration in production gRPC servers
|
|
250
|
+
- Plaintext gRPC channels in production client configuration
|
|
251
|
+
|
|
252
|
+
Insecure TLS is `critical` severity.
|
|
253
|
+
|
|
254
|
+
### 5. gRPC Reflection Enabled in Production
|
|
255
|
+
|
|
256
|
+
Detect gRPC reflection service that may expose service definitions:
|
|
257
|
+
- `grpc.reflection.v1alpha` or `grpc.reflection.v1` service registered without environment guard
|
|
258
|
+
- Reflection service enabled unconditionally (similar risk to GraphQL introspection)
|
|
259
|
+
|
|
260
|
+
Reflection in production is `medium` severity.
|
|
261
|
+
|
|
262
|
+
## Phase 3: False-Positive Mitigation — Inherited Auth
|
|
263
|
+
|
|
264
|
+
Before flagging an endpoint as "missing authentication middleware," trace the middleware chain upward:
|
|
265
|
+
|
|
266
|
+
#### Java/Spring Security
|
|
267
|
+
- `HttpSecurity.authorizeRequests().anyRequest().authenticated()` — app-level
|
|
268
|
+
- `@PreAuthorize` on controller class — class-level
|
|
269
|
+
- `SecurityFilterChain` bean — app-level
|
|
270
|
+
- `.antMatchers("/api/**").authenticated()` — path-level
|
|
271
|
+
|
|
272
|
+
#### Node/Express Middleware
|
|
273
|
+
- `app.use(authMiddleware)` — app-level
|
|
274
|
+
- `router.use(passport.authenticate('jwt'))` — router-level
|
|
275
|
+
- `app.use('/api', authMiddleware, apiRouter)` — path-level
|
|
276
|
+
|
|
277
|
+
#### Django Permissions
|
|
278
|
+
- `REST_FRAMEWORK.DEFAULT_PERMISSION_CLASSES: [IsAuthenticated]` — app-level
|
|
279
|
+
- `LoginRequiredMixin` — class-level
|
|
280
|
+
- `@login_required` — function-level
|
|
281
|
+
|
|
282
|
+
#### Go/Gin Middleware
|
|
283
|
+
- `r.Use(JWTAuth())` — app-level
|
|
284
|
+
- `group := r.Group("/api"); group.Use(AuthMiddleware())` — group-level
|
|
285
|
+
|
|
286
|
+
#### GraphQL Inherited Auth
|
|
287
|
+
- Apollo Server `context` function that validates JWT and sets `context.user` — app-level
|
|
288
|
+
- `graphql-shield` rule tree applied via `applyMiddleware` — schema-level
|
|
289
|
+
- NestJS `@UseGuards(AuthGuard)` on resolver class — class-level
|
|
290
|
+
- Apollo Federation gateway-level auth that validates before routing to subgraphs — gateway-level
|
|
291
|
+
|
|
292
|
+
#### gRPC Inherited Auth
|
|
293
|
+
- Global auth interceptor registered via `grpc.UnaryInterceptor(authInterceptor)` — server-level
|
|
294
|
+
- `ServerInterceptor` added to server builder interceptor chain — server-level
|
|
295
|
+
- Per-service interceptor applied at `addService` — service-level
|
|
296
|
+
- TLS mutual authentication (mTLS) at transport level — transport-level
|
|
297
|
+
|
|
298
|
+
## Phase 4: Infrastructure Security Patterns (E12-S6)
|
|
299
|
+
|
|
300
|
+
**Apply ONLY when {project_type} is `infrastructure` or `platform`.**
|
|
301
|
+
|
|
302
|
+
### 4a. Exposed Ports in Kubernetes Manifests
|
|
303
|
+
|
|
304
|
+
Detect Kubernetes Services and Pods that expose ports unnecessarily or without documentation.
|
|
305
|
+
|
|
306
|
+
**Flag these:**
|
|
307
|
+
- `NodePort` services exposing ports to external traffic without documented justification
|
|
308
|
+
- `hostPort` usage in Pod specs (exposes container port on the node's IP)
|
|
309
|
+
- Services with `type: LoadBalancer` without IP whitelisting or security group restrictions
|
|
310
|
+
- Pods with `hostNetwork: true` (shares the node's network namespace)
|
|
311
|
+
- Containers listening on privileged ports (< 1024) without documented need
|
|
312
|
+
|
|
313
|
+
**Severity:** `high` for NodePort/LoadBalancer exposure, `critical` for hostNetwork/hostPort
|
|
314
|
+
|
|
315
|
+
### 4b. Permissive Ingress Rules
|
|
316
|
+
|
|
317
|
+
Detect overly permissive network ingress rules in Kubernetes Ingress resources, cloud security groups, and firewall rules.
|
|
318
|
+
|
|
319
|
+
**Flag these:**
|
|
320
|
+
- Kubernetes Ingress resources without TLS configuration
|
|
321
|
+
- Ingress rules with wildcard hosts: `host: "*"` or missing host field
|
|
322
|
+
- AWS Security Groups with `0.0.0.0/0` ingress on non-standard ports
|
|
323
|
+
- Terraform `aws_security_group_rule` with `cidr_blocks = ["0.0.0.0/0"]` on ports other than 80/443
|
|
324
|
+
- GCP firewall rules with `source_ranges = ["0.0.0.0/0"]` without service account filtering
|
|
325
|
+
- Azure NSG rules with `source_address_prefix = "*"` on sensitive ports
|
|
326
|
+
|
|
327
|
+
**Severity:** `critical` for `0.0.0.0/0` on sensitive ports (SSH/22, DB/3306/5432, admin ports), `high` for permissive ingress on standard ports
|
|
328
|
+
|
|
329
|
+
### 4c. Overly Broad RBAC Bindings
|
|
330
|
+
|
|
331
|
+
Detect Kubernetes RBAC configurations that grant excessive permissions.
|
|
332
|
+
|
|
333
|
+
**Flag these:**
|
|
334
|
+
- `ClusterRoleBinding` bound to `cluster-admin` for non-system service accounts
|
|
335
|
+
- `RoleBinding` or `ClusterRoleBinding` with `resources: ["*"]` and `verbs: ["*"]`
|
|
336
|
+
- Service accounts with `automountServiceAccountToken: true` when not needed
|
|
337
|
+
- `ClusterRole` with `apiGroups: ["*"]` granting access to all API groups
|
|
338
|
+
- Roles that grant `create`, `delete`, or `patch` on `secrets` without namespace scoping
|
|
339
|
+
- Default service account with non-default permissions
|
|
340
|
+
|
|
341
|
+
**Severity:** `critical` for cluster-admin bindings and wildcard permissions, `high` for broad secret access
|
|
342
|
+
|
|
343
|
+
### 4d. Missing NetworkPolicy
|
|
344
|
+
|
|
345
|
+
Detect Kubernetes namespaces and workloads without NetworkPolicy enforcement.
|
|
346
|
+
|
|
347
|
+
**Flag these:**
|
|
348
|
+
- Namespaces with no NetworkPolicy resources defined (all traffic allowed by default)
|
|
349
|
+
- Pods in namespaces where NetworkPolicy exists but does not select them (via label selectors)
|
|
350
|
+
- NetworkPolicy with empty `ingress` or `egress` rules (allows all traffic of that type)
|
|
351
|
+
- Workloads in production namespaces without both ingress AND egress NetworkPolicy
|
|
352
|
+
- Multi-tenant clusters without namespace-level network isolation
|
|
353
|
+
|
|
354
|
+
**Severity:** `high` for missing NetworkPolicy in production, `medium` for missing in non-production
|
|
355
|
+
|
|
356
|
+
## Output Format
|
|
357
|
+
|
|
358
|
+
### Gap Entry Structure
|
|
359
|
+
|
|
360
|
+
Each finding MUST use the standardized gap schema from `gap-entry-schema.md`:
|
|
361
|
+
|
|
362
|
+
```yaml
|
|
363
|
+
gap:
|
|
364
|
+
id: "GAP-SECURITY-{seq}"
|
|
365
|
+
category: "security-endpoint"
|
|
366
|
+
severity: "{critical|high}"
|
|
367
|
+
title: "Short description (max 80 chars)"
|
|
368
|
+
description: "What was found, why it matters, what security implication it has"
|
|
369
|
+
evidence:
|
|
370
|
+
file: "relative/path/to/file"
|
|
371
|
+
line: 42
|
|
372
|
+
protocol: "rest"
|
|
373
|
+
recommendation: "Actionable fix — add middleware, validate input, filter response"
|
|
374
|
+
verified_by: "machine-detected"
|
|
375
|
+
confidence: "{high|medium|low}"
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
**Protocol field:** Every gap entry MUST include a `protocol` field in the evidence section indicating which API protocol the finding applies to: `rest`, `graphql`, or `grpc`. This enables downstream consumers to filter and route findings by protocol.
|
|
379
|
+
|
|
380
|
+
#### GraphQL Gap Example
|
|
381
|
+
|
|
382
|
+
```yaml
|
|
383
|
+
gap:
|
|
384
|
+
id: "GAP-SECURITY-015"
|
|
385
|
+
category: "security-endpoint"
|
|
386
|
+
severity: "critical"
|
|
387
|
+
title: "Mutation resolver missing authorization checks"
|
|
388
|
+
description: "createUser mutation has no @auth directive or guard. Any authenticated user can create accounts."
|
|
389
|
+
evidence:
|
|
390
|
+
file: "src/graphql/resolvers/user.resolver.ts"
|
|
391
|
+
line: 42
|
|
392
|
+
protocol: "graphql"
|
|
393
|
+
recommendation: "Add @UseGuards(AuthGuard, RolesGuard) or @auth directive to the createUser mutation."
|
|
394
|
+
verified_by: "machine-detected"
|
|
395
|
+
confidence: "high"
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
#### gRPC Gap Example
|
|
399
|
+
|
|
400
|
+
```yaml
|
|
401
|
+
gap:
|
|
402
|
+
id: "GAP-SECURITY-022"
|
|
403
|
+
category: "security-endpoint"
|
|
404
|
+
severity: "critical"
|
|
405
|
+
title: "gRPC server missing auth interceptor in production config"
|
|
406
|
+
description: "Server setup uses grpc.insecure_port without TLS. No auth interceptor in interceptor chain."
|
|
407
|
+
evidence:
|
|
408
|
+
file: "cmd/server/main.go"
|
|
409
|
+
line: 58
|
|
410
|
+
protocol: "grpc"
|
|
411
|
+
recommendation: "Add TLS credentials and an auth interceptor to the gRPC server configuration."
|
|
412
|
+
verified_by: "machine-detected"
|
|
413
|
+
confidence: "high"
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Confidence Classification
|
|
417
|
+
|
|
418
|
+
- **high** — exact pattern match (e.g., no auth decorator/annotation on a `@PostMapping` handler)
|
|
419
|
+
- **medium** — heuristic match (e.g., handler accesses path parameter without obvious ownership check)
|
|
420
|
+
- **low** — ambiguous case (e.g., custom auth mechanism not recognized by pattern table)
|
|
421
|
+
|
|
422
|
+
### Budget Enforcement
|
|
423
|
+
|
|
424
|
+
Each gap entry should average approximately 100 tokens in structured YAML format.
|
|
425
|
+
Maximum output: 70 gap entries per scan.
|
|
426
|
+
|
|
427
|
+
If more than 70 gaps are detected:
|
|
428
|
+
1. Sort all findings by severity (critical > high)
|
|
429
|
+
2. Within same severity, sort by confidence (high > medium > low)
|
|
430
|
+
3. Keep the top 70 entries
|
|
431
|
+
4. Append a budget summary section:
|
|
432
|
+
|
|
433
|
+
```markdown
|
|
434
|
+
## Budget Summary
|
|
435
|
+
Total gaps detected: {N}. Showing top 70 by severity. Omitted: {N-70} entries.
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
## Output File
|
|
439
|
+
|
|
440
|
+
Write all findings to: `{planning_artifacts}/brownfield-scan-security.md`
|