|
3251 | 3251 | "additionalProperties": false |
3252 | 3252 | } |
3253 | 3253 | }, |
| 3254 | + "alerting": { |
| 3255 | + "type": "object", |
| 3256 | + "description": "Declarative alert channels, rules, and global alerting settings synced into the config store at startup.", |
| 3257 | + "properties": { |
| 3258 | + "history_retention_days": { |
| 3259 | + "type": "integer", |
| 3260 | + "minimum": 0, |
| 3261 | + "default": 365, |
| 3262 | + "description": "Days to retain alert history (0 = no pruning)" |
| 3263 | + }, |
| 3264 | + "webhook_network": { |
| 3265 | + "type": "object", |
| 3266 | + "description": "Outbound URL validation controls for webhook-based alert channels", |
| 3267 | + "properties": { |
| 3268 | + "allow_http": { |
| 3269 | + "type": "boolean", |
| 3270 | + "default": false, |
| 3271 | + "description": "Allow http (not just https) webhook URLs" |
| 3272 | + }, |
| 3273 | + "allow_private_network": { |
| 3274 | + "type": "boolean", |
| 3275 | + "default": false, |
| 3276 | + "description": "Allow webhooks targeting private or loopback addresses" |
| 3277 | + } |
| 3278 | + }, |
| 3279 | + "additionalProperties": false |
| 3280 | + }, |
| 3281 | + "channels": { |
| 3282 | + "type": "array", |
| 3283 | + "description": "Declarative alert channels (Slack, Microsoft Teams, PagerDuty, generic webhook)", |
| 3284 | + "items": { |
| 3285 | + "type": "object", |
| 3286 | + "properties": { |
| 3287 | + "id": { "type": "string", "description": "Stable channel ID" }, |
| 3288 | + "name": { "type": "string", "description": "Operator-facing channel name" }, |
| 3289 | + "description": { "type": "string" }, |
| 3290 | + "type": { |
| 3291 | + "type": "string", |
| 3292 | + "enum": ["slack", "microsoft_teams", "pagerduty", "webhook"], |
| 3293 | + "description": "Channel delivery type" |
| 3294 | + }, |
| 3295 | + "enabled": { "type": "boolean" }, |
| 3296 | + "cooldown_seconds": { |
| 3297 | + "type": "integer", |
| 3298 | + "minimum": 0, |
| 3299 | + "description": "Minimum seconds between sends for this channel" |
| 3300 | + }, |
| 3301 | + "config": { |
| 3302 | + "type": "object", |
| 3303 | + "description": "Channel-specific delivery configuration. Slack and Microsoft Teams use webhook_url or url. PagerDuty uses routing_key or integration_key. Generic webhook uses url or webhook_url, plus optional string headers.", |
| 3304 | + "additionalProperties": true |
| 3305 | + } |
| 3306 | + }, |
| 3307 | + "required": ["id", "name", "type", "enabled", "config"], |
| 3308 | + "allOf": [ |
| 3309 | + { |
| 3310 | + "if": { |
| 3311 | + "properties": { "type": { "const": "slack" } }, |
| 3312 | + "required": ["type"] |
| 3313 | + }, |
| 3314 | + "then": { |
| 3315 | + "properties": { |
| 3316 | + "config": { |
| 3317 | + "type": "object", |
| 3318 | + "properties": { |
| 3319 | + "webhook_url": { |
| 3320 | + "type": "string", |
| 3321 | + "minLength": 1, |
| 3322 | + "anyOf": [{ "format": "uri" }, { "pattern": "^env\\.[A-Za-z_][A-Za-z0-9_]*$" }], |
| 3323 | + "description": "Slack incoming webhook URL. Supports env.VAR_NAME references." |
| 3324 | + }, |
| 3325 | + "url": { |
| 3326 | + "type": "string", |
| 3327 | + "minLength": 1, |
| 3328 | + "anyOf": [{ "format": "uri" }, { "pattern": "^env\\.[A-Za-z_][A-Za-z0-9_]*$" }], |
| 3329 | + "description": "Alias for webhook_url. Supports env.VAR_NAME references." |
| 3330 | + } |
| 3331 | + }, |
| 3332 | + "oneOf": [{ "required": ["webhook_url"] }, { "required": ["url"] }], |
| 3333 | + "additionalProperties": true |
| 3334 | + } |
| 3335 | + }, |
| 3336 | + "required": ["config"] |
| 3337 | + } |
| 3338 | + }, |
| 3339 | + { |
| 3340 | + "if": { |
| 3341 | + "properties": { "type": { "const": "microsoft_teams" } }, |
| 3342 | + "required": ["type"] |
| 3343 | + }, |
| 3344 | + "then": { |
| 3345 | + "properties": { |
| 3346 | + "config": { |
| 3347 | + "type": "object", |
| 3348 | + "properties": { |
| 3349 | + "webhook_url": { |
| 3350 | + "type": "string", |
| 3351 | + "minLength": 1, |
| 3352 | + "anyOf": [{ "format": "uri" }, { "pattern": "^env\\.[A-Za-z_][A-Za-z0-9_]*$" }], |
| 3353 | + "description": "Microsoft Teams incoming webhook or workflow URL. Supports env.VAR_NAME references." |
| 3354 | + }, |
| 3355 | + "url": { |
| 3356 | + "type": "string", |
| 3357 | + "minLength": 1, |
| 3358 | + "anyOf": [{ "format": "uri" }, { "pattern": "^env\\.[A-Za-z_][A-Za-z0-9_]*$" }], |
| 3359 | + "description": "Alias for webhook_url. Supports env.VAR_NAME references." |
| 3360 | + } |
| 3361 | + }, |
| 3362 | + "oneOf": [{ "required": ["webhook_url"] }, { "required": ["url"] }], |
| 3363 | + "additionalProperties": true |
| 3364 | + } |
| 3365 | + }, |
| 3366 | + "required": ["config"] |
| 3367 | + } |
| 3368 | + }, |
| 3369 | + { |
| 3370 | + "if": { |
| 3371 | + "properties": { "type": { "const": "pagerduty" } }, |
| 3372 | + "required": ["type"] |
| 3373 | + }, |
| 3374 | + "then": { |
| 3375 | + "properties": { |
| 3376 | + "config": { |
| 3377 | + "type": "object", |
| 3378 | + "properties": { |
| 3379 | + "routing_key": { |
| 3380 | + "type": "string", |
| 3381 | + "minLength": 1, |
| 3382 | + "description": "PagerDuty Events API v2 integration key. Supports env.VAR_NAME references." |
| 3383 | + }, |
| 3384 | + "integration_key": { |
| 3385 | + "type": "string", |
| 3386 | + "minLength": 1, |
| 3387 | + "description": "Alias for routing_key. Supports env.VAR_NAME references." |
| 3388 | + } |
| 3389 | + }, |
| 3390 | + "oneOf": [{ "required": ["routing_key"] }, { "required": ["integration_key"] }], |
| 3391 | + "additionalProperties": true |
| 3392 | + } |
| 3393 | + }, |
| 3394 | + "required": ["config"] |
| 3395 | + } |
| 3396 | + }, |
| 3397 | + { |
| 3398 | + "if": { |
| 3399 | + "properties": { "type": { "const": "webhook" } }, |
| 3400 | + "required": ["type"] |
| 3401 | + }, |
| 3402 | + "then": { |
| 3403 | + "properties": { |
| 3404 | + "config": { |
| 3405 | + "type": "object", |
| 3406 | + "properties": { |
| 3407 | + "url": { |
| 3408 | + "type": "string", |
| 3409 | + "minLength": 1, |
| 3410 | + "anyOf": [{ "format": "uri" }, { "pattern": "^env\\.[A-Za-z_][A-Za-z0-9_]*$" }], |
| 3411 | + "description": "Generic webhook URL. Supports env.VAR_NAME references." |
| 3412 | + }, |
| 3413 | + "webhook_url": { |
| 3414 | + "type": "string", |
| 3415 | + "minLength": 1, |
| 3416 | + "anyOf": [{ "format": "uri" }, { "pattern": "^env\\.[A-Za-z_][A-Za-z0-9_]*$" }], |
| 3417 | + "description": "Alias for url. Supports env.VAR_NAME references." |
| 3418 | + }, |
| 3419 | + "headers": { |
| 3420 | + "type": "object", |
| 3421 | + "description": "Optional headers to send with the webhook request. Values support env.VAR_NAME references. Sensitive hop-by-hop headers are ignored at send time.", |
| 3422 | + "additionalProperties": { "type": "string" } |
| 3423 | + } |
| 3424 | + }, |
| 3425 | + "oneOf": [{ "required": ["url"] }, { "required": ["webhook_url"] }], |
| 3426 | + "additionalProperties": true |
| 3427 | + } |
| 3428 | + }, |
| 3429 | + "required": ["config"] |
| 3430 | + } |
| 3431 | + } |
| 3432 | + ], |
| 3433 | + "additionalProperties": false |
| 3434 | + } |
| 3435 | + }, |
| 3436 | + "rules": { |
| 3437 | + "type": "array", |
| 3438 | + "description": "Declarative alert rules evaluated against governance usage metrics", |
| 3439 | + "items": { |
| 3440 | + "type": "object", |
| 3441 | + "properties": { |
| 3442 | + "id": { "type": "string", "description": "Stable rule ID" }, |
| 3443 | + "name": { "type": "string", "description": "Operator-facing rule name" }, |
| 3444 | + "description": { "type": "string" }, |
| 3445 | + "enabled": { "type": "boolean" }, |
| 3446 | + "scope_type": { |
| 3447 | + "type": "string", |
| 3448 | + "enum": ["virtual_key", "team", "customer"], |
| 3449 | + "description": "Governance owner scope to evaluate" |
| 3450 | + }, |
| 3451 | + "scope_id": { "type": "string", "description": "ID of the virtual key, team, or customer" }, |
| 3452 | + "cel_expression": { |
| 3453 | + "type": "string", |
| 3454 | + "description": "CEL expression evaluated against usage variables (budget_usage_percent, budget_spent, request_usage, token_usage, etc.)" |
| 3455 | + }, |
| 3456 | + "query": { |
| 3457 | + "type": "object", |
| 3458 | + "description": "Optional UI query-builder representation of cel_expression", |
| 3459 | + "additionalProperties": true |
| 3460 | + }, |
| 3461 | + "cooldown_seconds": { |
| 3462 | + "type": "integer", |
| 3463 | + "minimum": 0, |
| 3464 | + "default": 60, |
| 3465 | + "description": "Minimum seconds between notifications for this rule" |
| 3466 | + }, |
| 3467 | + "notify_once_per_reset_cycle": { |
| 3468 | + "type": "boolean", |
| 3469 | + "default": false, |
| 3470 | + "description": "When true, notify at most once per budget/rate-limit reset cycle" |
| 3471 | + }, |
| 3472 | + "channel_ids": { |
| 3473 | + "type": "array", |
| 3474 | + "description": "IDs of channels to notify when this rule matches", |
| 3475 | + "items": { "type": "string", "minLength": 1 }, |
| 3476 | + "minItems": 1 |
| 3477 | + }, |
| 3478 | + "target_type": { |
| 3479 | + "type": "string", |
| 3480 | + "enum": ["budget"], |
| 3481 | + "description": "Explicit target type; pair with target_id to evaluate one specific budget" |
| 3482 | + }, |
| 3483 | + "target_id": { "type": "string", "description": "ID of the explicit target" } |
| 3484 | + }, |
| 3485 | + "required": ["id", "name", "enabled", "scope_type", "scope_id", "cel_expression", "channel_ids"], |
| 3486 | + "allOf": [ |
| 3487 | + { |
| 3488 | + "if": { |
| 3489 | + "required": ["target_type"] |
| 3490 | + }, |
| 3491 | + "then": { |
| 3492 | + "required": ["target_id"] |
| 3493 | + } |
| 3494 | + }, |
| 3495 | + { |
| 3496 | + "if": { |
| 3497 | + "required": ["target_id"] |
| 3498 | + }, |
| 3499 | + "then": { |
| 3500 | + "required": ["target_type"] |
| 3501 | + } |
| 3502 | + } |
| 3503 | + ], |
| 3504 | + "additionalProperties": false |
| 3505 | + } |
| 3506 | + } |
| 3507 | + }, |
| 3508 | + "additionalProperties": false |
| 3509 | + }, |
3254 | 3510 | "auditLogs": { |
3255 | 3511 | "type": "object", |
3256 | 3512 | "properties": { |
|
0 commit comments