feat: Initialize Zastava Webhook service with TLS and Authority authentication
- Added Program.cs to set up the web application with Serilog for logging, health check endpoints, and a placeholder admission endpoint. - Configured Kestrel server to use TLS 1.3 and handle client certificates appropriately. - Created StellaOps.Zastava.Webhook.csproj with necessary dependencies including Serilog and Polly. - Documented tasks in TASKS.md for the Zastava Webhook project, outlining current work and exit criteria for each task.
This commit is contained in:
		
							
								
								
									
										73
									
								
								docs/notify/schemas/notify-channel@1.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								docs/notify/schemas/notify-channel@1.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| { | ||||
|   "$id": "https://stella-ops.org/schemas/notify/notify-channel@1.json", | ||||
|   "$schema": "http://json-schema.org/draft-07/schema#", | ||||
|   "title": "Notify Channel", | ||||
|   "type": "object", | ||||
|   "required": [ | ||||
|     "schemaVersion", | ||||
|     "channelId", | ||||
|     "tenantId", | ||||
|     "name", | ||||
|     "type", | ||||
|     "config", | ||||
|     "enabled", | ||||
|     "createdAt", | ||||
|     "updatedAt" | ||||
|   ], | ||||
|   "properties": { | ||||
|     "schemaVersion": {"type": "string", "const": "notify.channel@1"}, | ||||
|     "channelId": {"type": "string"}, | ||||
|     "tenantId": {"type": "string"}, | ||||
|     "name": {"type": "string"}, | ||||
|     "type": { | ||||
|       "type": "string", | ||||
|       "enum": ["slack", "teams", "email", "webhook", "custom"] | ||||
|     }, | ||||
|     "displayName": {"type": "string"}, | ||||
|     "description": {"type": "string"}, | ||||
|     "config": {"$ref": "#/$defs/channelConfig"}, | ||||
|     "enabled": {"type": "boolean"}, | ||||
|     "labels": {"$ref": "#/$defs/stringMap"}, | ||||
|     "metadata": {"$ref": "#/$defs/stringMap"}, | ||||
|     "createdBy": {"type": "string"}, | ||||
|     "createdAt": {"type": "string", "format": "date-time"}, | ||||
|     "updatedBy": {"type": "string"}, | ||||
|     "updatedAt": {"type": "string", "format": "date-time"} | ||||
|   }, | ||||
|   "additionalProperties": false, | ||||
|   "$defs": { | ||||
|     "channelConfig": { | ||||
|       "type": "object", | ||||
|       "required": ["secretRef"], | ||||
|       "properties": { | ||||
|         "secretRef": {"type": "string"}, | ||||
|         "target": {"type": "string"}, | ||||
|         "endpoint": {"type": "string", "format": "uri"}, | ||||
|         "properties": {"$ref": "#/$defs/stringMap"}, | ||||
|         "limits": {"$ref": "#/$defs/channelLimits"} | ||||
|       }, | ||||
|       "additionalProperties": false | ||||
|     }, | ||||
|     "channelLimits": { | ||||
|       "type": "object", | ||||
|       "properties": { | ||||
|         "concurrency": {"type": "integer", "minimum": 1}, | ||||
|         "requestsPerMinute": {"type": "integer", "minimum": 1}, | ||||
|         "timeout": { | ||||
|           "type": "string", | ||||
|           "pattern": "^P(T.*)?$", | ||||
|           "description": "ISO 8601 duration" | ||||
|         }, | ||||
|         "maxBatchSize": {"type": "integer", "minimum": 1} | ||||
|       }, | ||||
|       "additionalProperties": false | ||||
|     }, | ||||
|     "stringMap": { | ||||
|       "type": "object", | ||||
|       "patternProperties": { | ||||
|         ".*": {"type": "string"} | ||||
|       }, | ||||
|       "additionalProperties": false | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										56
									
								
								docs/notify/schemas/notify-event@1.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								docs/notify/schemas/notify-event@1.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| { | ||||
|   "$id": "https://stella-ops.org/schemas/notify/notify-event@1.json", | ||||
|   "$schema": "http://json-schema.org/draft-07/schema#", | ||||
|   "title": "Notify Event Envelope", | ||||
|   "type": "object", | ||||
|   "required": ["eventId", "kind", "tenant", "ts", "payload"], | ||||
|   "properties": { | ||||
|     "eventId": {"type": "string", "format": "uuid"}, | ||||
|     "kind": { | ||||
|       "type": "string", | ||||
|       "description": "Event kind identifier (e.g. scanner.report.ready).", | ||||
|       "enum": [ | ||||
|         "scanner.report.ready", | ||||
|         "scanner.scan.completed", | ||||
|         "scheduler.rescan.delta", | ||||
|         "attestor.logged", | ||||
|         "zastava.admission", | ||||
|         "feedser.export.completed", | ||||
|         "vexer.export.completed" | ||||
|       ] | ||||
|     }, | ||||
|     "version": {"type": "string"}, | ||||
|     "tenant": {"type": "string"}, | ||||
|     "ts": {"type": "string", "format": "date-time"}, | ||||
|     "actor": {"type": "string"}, | ||||
|     "scope": { | ||||
|       "type": "object", | ||||
|       "properties": { | ||||
|         "namespace": {"type": "string"}, | ||||
|         "repo": {"type": "string"}, | ||||
|         "digest": {"type": "string"}, | ||||
|         "component": {"type": "string"}, | ||||
|         "image": {"type": "string"}, | ||||
|         "labels": {"$ref": "#/$defs/stringMap"}, | ||||
|         "attributes": {"$ref": "#/$defs/stringMap"} | ||||
|       }, | ||||
|       "additionalProperties": false | ||||
|     }, | ||||
|     "payload": { | ||||
|       "type": "object", | ||||
|       "description": "Event specific body; see individual schemas for shapes.", | ||||
|       "additionalProperties": true | ||||
|     }, | ||||
|     "attributes": {"$ref": "#/$defs/stringMap"} | ||||
|   }, | ||||
|   "additionalProperties": false, | ||||
|   "$defs": { | ||||
|     "stringMap": { | ||||
|       "type": "object", | ||||
|       "patternProperties": { | ||||
|         ".*": {"type": "string"} | ||||
|       }, | ||||
|       "additionalProperties": false | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										96
									
								
								docs/notify/schemas/notify-rule@1.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								docs/notify/schemas/notify-rule@1.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| { | ||||
|   "$id": "https://stella-ops.org/schemas/notify/notify-rule@1.json", | ||||
|   "$schema": "http://json-schema.org/draft-07/schema#", | ||||
|   "title": "Notify Rule", | ||||
|   "type": "object", | ||||
|   "required": [ | ||||
|     "schemaVersion", | ||||
|     "ruleId", | ||||
|     "tenantId", | ||||
|     "name", | ||||
|     "enabled", | ||||
|     "match", | ||||
|     "actions", | ||||
|     "createdAt", | ||||
|     "updatedAt" | ||||
|   ], | ||||
|   "properties": { | ||||
|     "schemaVersion": {"type": "string", "const": "notify.rule@1"}, | ||||
|     "ruleId": {"type": "string"}, | ||||
|     "tenantId": {"type": "string"}, | ||||
|     "name": {"type": "string"}, | ||||
|     "description": {"type": "string"}, | ||||
|     "enabled": {"type": "boolean"}, | ||||
|     "match": {"$ref": "#/$defs/ruleMatch"}, | ||||
|     "actions": { | ||||
|       "type": "array", | ||||
|       "minItems": 1, | ||||
|       "items": {"$ref": "#/$defs/ruleAction"} | ||||
|     }, | ||||
|     "labels": {"$ref": "#/$defs/stringMap"}, | ||||
|     "metadata": {"$ref": "#/$defs/stringMap"}, | ||||
|     "createdBy": {"type": "string"}, | ||||
|     "createdAt": {"type": "string", "format": "date-time"}, | ||||
|     "updatedBy": {"type": "string"}, | ||||
|     "updatedAt": {"type": "string", "format": "date-time"} | ||||
|   }, | ||||
|   "additionalProperties": false, | ||||
|   "$defs": { | ||||
|     "ruleMatch": { | ||||
|       "type": "object", | ||||
|       "properties": { | ||||
|         "eventKinds": {"$ref": "#/$defs/stringArray"}, | ||||
|         "namespaces": {"$ref": "#/$defs/stringArray"}, | ||||
|         "repositories": {"$ref": "#/$defs/stringArray"}, | ||||
|         "digests": {"$ref": "#/$defs/stringArray"}, | ||||
|         "labels": {"$ref": "#/$defs/stringArray"}, | ||||
|         "componentPurls": {"$ref": "#/$defs/stringArray"}, | ||||
|         "minSeverity": {"type": "string"}, | ||||
|         "verdicts": {"$ref": "#/$defs/stringArray"}, | ||||
|         "kevOnly": {"type": "boolean"}, | ||||
|         "vex": {"$ref": "#/$defs/ruleMatchVex"} | ||||
|       }, | ||||
|       "additionalProperties": false | ||||
|     }, | ||||
|     "ruleMatchVex": { | ||||
|       "type": "object", | ||||
|       "properties": { | ||||
|         "includeAcceptedJustifications": {"type": "boolean"}, | ||||
|         "includeRejectedJustifications": {"type": "boolean"}, | ||||
|         "includeUnknownJustifications": {"type": "boolean"}, | ||||
|         "justificationKinds": {"$ref": "#/$defs/stringArray"} | ||||
|       }, | ||||
|       "additionalProperties": false | ||||
|     }, | ||||
|     "ruleAction": { | ||||
|       "type": "object", | ||||
|       "required": ["actionId", "channel", "enabled"], | ||||
|       "properties": { | ||||
|         "actionId": {"type": "string"}, | ||||
|         "channel": {"type": "string"}, | ||||
|         "template": {"type": "string"}, | ||||
|         "digest": {"type": "string"}, | ||||
|         "throttle": { | ||||
|           "type": "string", | ||||
|           "pattern": "^P(T.*)?$", | ||||
|           "description": "ISO 8601 duration" | ||||
|         }, | ||||
|         "locale": {"type": "string"}, | ||||
|         "enabled": {"type": "boolean"}, | ||||
|         "metadata": {"$ref": "#/$defs/stringMap"} | ||||
|       }, | ||||
|       "additionalProperties": false | ||||
|     }, | ||||
|     "stringArray": { | ||||
|       "type": "array", | ||||
|       "items": {"type": "string"} | ||||
|     }, | ||||
|     "stringMap": { | ||||
|       "type": "object", | ||||
|       "patternProperties": { | ||||
|         ".*": {"type": "string"} | ||||
|       }, | ||||
|       "additionalProperties": false | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										55
									
								
								docs/notify/schemas/notify-template@1.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								docs/notify/schemas/notify-template@1.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| { | ||||
|   "$id": "https://stella-ops.org/schemas/notify/notify-template@1.json", | ||||
|   "$schema": "http://json-schema.org/draft-07/schema#", | ||||
|   "title": "Notify Template", | ||||
|   "type": "object", | ||||
|   "required": [ | ||||
|     "schemaVersion", | ||||
|     "templateId", | ||||
|     "tenantId", | ||||
|     "channelType", | ||||
|     "key", | ||||
|     "locale", | ||||
|     "body", | ||||
|     "renderMode", | ||||
|     "format", | ||||
|     "createdAt", | ||||
|     "updatedAt" | ||||
|   ], | ||||
|   "properties": { | ||||
|     "schemaVersion": {"type": "string", "const": "notify.template@1"}, | ||||
|     "templateId": {"type": "string"}, | ||||
|     "tenantId": {"type": "string"}, | ||||
|     "channelType": { | ||||
|       "type": "string", | ||||
|       "enum": ["slack", "teams", "email", "webhook", "custom"] | ||||
|     }, | ||||
|     "key": {"type": "string"}, | ||||
|     "locale": {"type": "string"}, | ||||
|     "body": {"type": "string"}, | ||||
|     "description": {"type": "string"}, | ||||
|     "renderMode": { | ||||
|       "type": "string", | ||||
|       "enum": ["markdown", "html", "adaptiveCard", "plainText", "json"] | ||||
|     }, | ||||
|     "format": { | ||||
|       "type": "string", | ||||
|       "enum": ["slack", "teams", "email", "webhook", "json"] | ||||
|     }, | ||||
|     "metadata": {"$ref": "#/$defs/stringMap"}, | ||||
|     "createdBy": {"type": "string"}, | ||||
|     "createdAt": {"type": "string", "format": "date-time"}, | ||||
|     "updatedBy": {"type": "string"}, | ||||
|     "updatedAt": {"type": "string", "format": "date-time"} | ||||
|   }, | ||||
|   "additionalProperties": false, | ||||
|   "$defs": { | ||||
|     "stringMap": { | ||||
|       "type": "object", | ||||
|       "patternProperties": { | ||||
|         ".*": {"type": "string"} | ||||
|       }, | ||||
|       "additionalProperties": false | ||||
|     } | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user