Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
- Added IPackRunIncidentModeService interface for managing incident mode activation, deactivation, and status retrieval. - Created PackRunIncidentModeService class implementing the service interface with methods for activating, deactivating, and escalating incident modes. - Introduced incident mode status model (PackRunIncidentModeStatus) and related enums for escalation levels and activation sources. - Developed retention policy, telemetry settings, and debug capture settings models to manage incident mode configurations. - Implemented SLO breach notification handling to activate incident mode based on severity. - Added in-memory store (InMemoryPackRunIncidentModeStore) for testing purposes. - Created comprehensive unit tests for incident mode service, covering activation, deactivation, status retrieval, and SLO breach handling.
642 lines
18 KiB
JSON
642 lines
18 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://stella-ops.org/schemas/security-scopes-matrix.schema.json",
|
|
"title": "StellaOps Security Scopes Matrix Schema",
|
|
"description": "Schema for security scopes, roles, permissions, and privacy controls. Unblocks DOCS-SEC-62-001, DOCS-SEC-OBS-50-001 (2+ tasks).",
|
|
"type": "object",
|
|
"definitions": {
|
|
"Scope": {
|
|
"type": "object",
|
|
"description": "OAuth2/OIDC scope definition",
|
|
"required": ["scope_id", "name"],
|
|
"properties": {
|
|
"scope_id": {
|
|
"type": "string",
|
|
"pattern": "^[a-z][a-z0-9_:]+$",
|
|
"description": "Scope identifier (e.g., findings:read, admin:write)"
|
|
},
|
|
"name": {
|
|
"type": "string"
|
|
},
|
|
"description": {
|
|
"type": "string"
|
|
},
|
|
"category": {
|
|
"type": "string",
|
|
"enum": ["read", "write", "admin", "system"],
|
|
"description": "Scope category"
|
|
},
|
|
"resource": {
|
|
"type": "string",
|
|
"description": "Resource this scope applies to"
|
|
},
|
|
"actions": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string",
|
|
"enum": ["create", "read", "update", "delete", "list", "execute", "export", "import"]
|
|
}
|
|
},
|
|
"requires_mfa": {
|
|
"type": "boolean",
|
|
"default": false,
|
|
"description": "Whether MFA is required for this scope"
|
|
},
|
|
"sensitive": {
|
|
"type": "boolean",
|
|
"default": false,
|
|
"description": "Whether this scope accesses sensitive data"
|
|
},
|
|
"audit_level": {
|
|
"type": "string",
|
|
"enum": ["none", "basic", "detailed", "full"],
|
|
"default": "basic"
|
|
},
|
|
"parent_scope": {
|
|
"type": "string",
|
|
"description": "Parent scope that implies this scope"
|
|
}
|
|
}
|
|
},
|
|
"Role": {
|
|
"type": "object",
|
|
"description": "Role definition with assigned scopes",
|
|
"required": ["role_id", "name", "scopes"],
|
|
"properties": {
|
|
"role_id": {
|
|
"type": "string"
|
|
},
|
|
"name": {
|
|
"type": "string"
|
|
},
|
|
"description": {
|
|
"type": "string"
|
|
},
|
|
"type": {
|
|
"type": "string",
|
|
"enum": ["system", "tenant", "project", "custom"],
|
|
"description": "Role type"
|
|
},
|
|
"scopes": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "Scopes assigned to this role"
|
|
},
|
|
"inherits_from": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "Roles this role inherits from"
|
|
},
|
|
"restrictions": {
|
|
"$ref": "#/definitions/RoleRestrictions"
|
|
},
|
|
"metadata": {
|
|
"type": "object",
|
|
"additionalProperties": true
|
|
}
|
|
}
|
|
},
|
|
"RoleRestrictions": {
|
|
"type": "object",
|
|
"description": "Restrictions on role usage",
|
|
"properties": {
|
|
"max_sessions": {
|
|
"type": "integer",
|
|
"description": "Maximum concurrent sessions"
|
|
},
|
|
"ip_allowlist": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"time_restrictions": {
|
|
"type": "object",
|
|
"properties": {
|
|
"allowed_hours": {
|
|
"type": "object",
|
|
"properties": {
|
|
"start": {
|
|
"type": "string",
|
|
"pattern": "^[0-2][0-9]:[0-5][0-9]$"
|
|
},
|
|
"end": {
|
|
"type": "string",
|
|
"pattern": "^[0-2][0-9]:[0-5][0-9]$"
|
|
},
|
|
"timezone": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"allowed_days": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string",
|
|
"enum": ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"require_approval": {
|
|
"type": "boolean",
|
|
"description": "Require approval for role activation"
|
|
}
|
|
}
|
|
},
|
|
"Permission": {
|
|
"type": "object",
|
|
"description": "Fine-grained permission",
|
|
"required": ["permission_id", "resource", "action"],
|
|
"properties": {
|
|
"permission_id": {
|
|
"type": "string"
|
|
},
|
|
"resource": {
|
|
"type": "string"
|
|
},
|
|
"action": {
|
|
"type": "string",
|
|
"enum": ["create", "read", "update", "delete", "list", "execute", "export", "import"]
|
|
},
|
|
"conditions": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/PermissionCondition"
|
|
}
|
|
},
|
|
"effect": {
|
|
"type": "string",
|
|
"enum": ["allow", "deny"],
|
|
"default": "allow"
|
|
}
|
|
}
|
|
},
|
|
"PermissionCondition": {
|
|
"type": "object",
|
|
"description": "Condition for permission evaluation",
|
|
"required": ["type", "value"],
|
|
"properties": {
|
|
"type": {
|
|
"type": "string",
|
|
"enum": ["attribute", "context", "time", "resource_owner", "tenant"]
|
|
},
|
|
"attribute": {
|
|
"type": "string"
|
|
},
|
|
"operator": {
|
|
"type": "string",
|
|
"enum": ["eq", "neq", "in", "not_in", "contains", "gt", "lt", "gte", "lte"]
|
|
},
|
|
"value": {}
|
|
}
|
|
},
|
|
"TenancyHeader": {
|
|
"type": "object",
|
|
"description": "Multi-tenancy header specification",
|
|
"required": ["header_name", "required"],
|
|
"properties": {
|
|
"header_name": {
|
|
"type": "string",
|
|
"default": "X-Tenant-ID"
|
|
},
|
|
"required": {
|
|
"type": "boolean",
|
|
"default": true
|
|
},
|
|
"validation": {
|
|
"type": "object",
|
|
"properties": {
|
|
"format": {
|
|
"type": "string",
|
|
"enum": ["uuid", "slug", "custom"]
|
|
},
|
|
"pattern": {
|
|
"type": "string"
|
|
},
|
|
"max_length": {
|
|
"type": "integer"
|
|
}
|
|
}
|
|
},
|
|
"default_value": {
|
|
"type": "string",
|
|
"description": "Default tenant if header not provided"
|
|
},
|
|
"extract_from_token": {
|
|
"type": "boolean",
|
|
"default": true,
|
|
"description": "Allow extraction from JWT token"
|
|
},
|
|
"token_claim": {
|
|
"type": "string",
|
|
"default": "tenant_id"
|
|
}
|
|
}
|
|
},
|
|
"PrivacyControl": {
|
|
"type": "object",
|
|
"description": "Privacy control configuration",
|
|
"required": ["control_id", "name"],
|
|
"properties": {
|
|
"control_id": {
|
|
"type": "string"
|
|
},
|
|
"name": {
|
|
"type": "string"
|
|
},
|
|
"description": {
|
|
"type": "string"
|
|
},
|
|
"data_classification": {
|
|
"type": "string",
|
|
"enum": ["public", "internal", "confidential", "restricted", "pii", "phi"]
|
|
},
|
|
"redaction_policy": {
|
|
"$ref": "#/definitions/RedactionPolicy"
|
|
},
|
|
"retention_policy": {
|
|
"$ref": "#/definitions/RetentionPolicy"
|
|
},
|
|
"consent_required": {
|
|
"type": "boolean",
|
|
"default": false
|
|
},
|
|
"audit_access": {
|
|
"type": "boolean",
|
|
"default": true
|
|
}
|
|
}
|
|
},
|
|
"RedactionPolicy": {
|
|
"type": "object",
|
|
"description": "Data redaction policy",
|
|
"properties": {
|
|
"policy_id": {
|
|
"type": "string"
|
|
},
|
|
"name": {
|
|
"type": "string"
|
|
},
|
|
"rules": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/RedactionRule"
|
|
}
|
|
},
|
|
"default_action": {
|
|
"type": "string",
|
|
"enum": ["pass", "mask", "hash", "remove"],
|
|
"default": "pass"
|
|
}
|
|
}
|
|
},
|
|
"RedactionRule": {
|
|
"type": "object",
|
|
"description": "Individual redaction rule",
|
|
"required": ["field_pattern", "action"],
|
|
"properties": {
|
|
"rule_id": {
|
|
"type": "string"
|
|
},
|
|
"field_pattern": {
|
|
"type": "string",
|
|
"description": "JSON path or field name pattern"
|
|
},
|
|
"data_type": {
|
|
"type": "string",
|
|
"enum": ["email", "phone", "ssn", "ip_address", "credit_card", "name", "address", "custom"]
|
|
},
|
|
"action": {
|
|
"type": "string",
|
|
"enum": ["mask", "hash", "remove", "tokenize", "truncate"]
|
|
},
|
|
"mask_char": {
|
|
"type": "string",
|
|
"default": "*"
|
|
},
|
|
"preserve_chars": {
|
|
"type": "integer",
|
|
"description": "Number of chars to preserve (e.g., last 4 of phone)"
|
|
},
|
|
"hash_algorithm": {
|
|
"type": "string",
|
|
"enum": ["sha256", "sha512", "hmac-sha256"]
|
|
},
|
|
"conditions": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/PermissionCondition"
|
|
},
|
|
"description": "Conditions when to apply redaction"
|
|
}
|
|
}
|
|
},
|
|
"RetentionPolicy": {
|
|
"type": "object",
|
|
"description": "Data retention policy",
|
|
"properties": {
|
|
"policy_id": {
|
|
"type": "string"
|
|
},
|
|
"name": {
|
|
"type": "string"
|
|
},
|
|
"default_retention_days": {
|
|
"type": "integer"
|
|
},
|
|
"rules": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"data_type": {
|
|
"type": "string"
|
|
},
|
|
"retention_days": {
|
|
"type": "integer"
|
|
},
|
|
"action_on_expiry": {
|
|
"type": "string",
|
|
"enum": ["delete", "archive", "anonymize"]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"legal_hold_enabled": {
|
|
"type": "boolean",
|
|
"default": false
|
|
}
|
|
}
|
|
},
|
|
"DebugOptIn": {
|
|
"type": "object",
|
|
"description": "Debug/diagnostic opt-in configuration",
|
|
"properties": {
|
|
"enabled": {
|
|
"type": "boolean",
|
|
"default": false
|
|
},
|
|
"opt_in_required": {
|
|
"type": "boolean",
|
|
"default": true
|
|
},
|
|
"scopes_required": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string"
|
|
},
|
|
"description": "Scopes required to access debug data"
|
|
},
|
|
"data_collected": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"data_type": {
|
|
"type": "string"
|
|
},
|
|
"description": {
|
|
"type": "string"
|
|
},
|
|
"retention_hours": {
|
|
"type": "integer"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"redaction_applied": {
|
|
"type": "boolean",
|
|
"default": true
|
|
}
|
|
}
|
|
},
|
|
"ScopeMatrix": {
|
|
"type": "object",
|
|
"description": "Complete scope matrix",
|
|
"required": ["version", "scopes"],
|
|
"properties": {
|
|
"version": {
|
|
"type": "string"
|
|
},
|
|
"updated_at": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
},
|
|
"scopes": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/Scope"
|
|
}
|
|
},
|
|
"roles": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/Role"
|
|
}
|
|
},
|
|
"tenancy_config": {
|
|
"$ref": "#/definitions/TenancyHeader"
|
|
},
|
|
"privacy_controls": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/PrivacyControl"
|
|
}
|
|
},
|
|
"debug_config": {
|
|
"$ref": "#/definitions/DebugOptIn"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"properties": {
|
|
"matrix": {
|
|
"$ref": "#/definitions/ScopeMatrix"
|
|
}
|
|
},
|
|
"examples": [
|
|
{
|
|
"matrix": {
|
|
"version": "2025.10.0",
|
|
"updated_at": "2025-12-06T10:00:00Z",
|
|
"scopes": [
|
|
{
|
|
"scope_id": "findings:read",
|
|
"name": "Read Findings",
|
|
"description": "Read vulnerability findings",
|
|
"category": "read",
|
|
"resource": "findings",
|
|
"actions": ["read", "list"],
|
|
"audit_level": "basic"
|
|
},
|
|
{
|
|
"scope_id": "findings:write",
|
|
"name": "Write Findings",
|
|
"description": "Create and update findings",
|
|
"category": "write",
|
|
"resource": "findings",
|
|
"actions": ["create", "update"],
|
|
"audit_level": "detailed",
|
|
"parent_scope": "findings:read"
|
|
},
|
|
{
|
|
"scope_id": "findings:delete",
|
|
"name": "Delete Findings",
|
|
"description": "Delete findings (requires approval)",
|
|
"category": "admin",
|
|
"resource": "findings",
|
|
"actions": ["delete"],
|
|
"requires_mfa": true,
|
|
"audit_level": "full",
|
|
"parent_scope": "findings:write"
|
|
},
|
|
{
|
|
"scope_id": "scanner:execute",
|
|
"name": "Execute Scans",
|
|
"description": "Initiate container scans",
|
|
"category": "write",
|
|
"resource": "scanner",
|
|
"actions": ["execute"],
|
|
"audit_level": "detailed"
|
|
},
|
|
{
|
|
"scope_id": "risk:read",
|
|
"name": "Read Risk Scores",
|
|
"description": "Access risk scoring data",
|
|
"category": "read",
|
|
"resource": "risk",
|
|
"actions": ["read", "list"],
|
|
"audit_level": "basic"
|
|
},
|
|
{
|
|
"scope_id": "admin:*",
|
|
"name": "Full Admin Access",
|
|
"description": "Full administrative access",
|
|
"category": "admin",
|
|
"resource": "*",
|
|
"actions": ["create", "read", "update", "delete", "list", "execute"],
|
|
"requires_mfa": true,
|
|
"sensitive": true,
|
|
"audit_level": "full"
|
|
}
|
|
],
|
|
"roles": [
|
|
{
|
|
"role_id": "viewer",
|
|
"name": "Viewer",
|
|
"description": "Read-only access to findings and risk data",
|
|
"type": "tenant",
|
|
"scopes": ["findings:read", "risk:read"]
|
|
},
|
|
{
|
|
"role_id": "analyst",
|
|
"name": "Security Analyst",
|
|
"description": "Can view and update findings, execute scans",
|
|
"type": "tenant",
|
|
"scopes": ["findings:read", "findings:write", "scanner:execute", "risk:read"],
|
|
"inherits_from": ["viewer"]
|
|
},
|
|
{
|
|
"role_id": "admin",
|
|
"name": "Tenant Admin",
|
|
"description": "Full tenant administrative access",
|
|
"type": "tenant",
|
|
"scopes": ["findings:read", "findings:write", "findings:delete", "scanner:execute", "risk:read", "risk:write"],
|
|
"inherits_from": ["analyst"],
|
|
"restrictions": {
|
|
"max_sessions": 3,
|
|
"require_approval": false
|
|
}
|
|
},
|
|
{
|
|
"role_id": "super_admin",
|
|
"name": "Super Admin",
|
|
"description": "System-wide administrative access",
|
|
"type": "system",
|
|
"scopes": ["admin:*"],
|
|
"restrictions": {
|
|
"max_sessions": 1,
|
|
"require_approval": true
|
|
}
|
|
}
|
|
],
|
|
"tenancy_config": {
|
|
"header_name": "X-Tenant-ID",
|
|
"required": true,
|
|
"validation": {
|
|
"format": "uuid"
|
|
},
|
|
"extract_from_token": true,
|
|
"token_claim": "tenant_id"
|
|
},
|
|
"privacy_controls": [
|
|
{
|
|
"control_id": "pii-protection",
|
|
"name": "PII Protection",
|
|
"description": "Protection for personally identifiable information",
|
|
"data_classification": "pii",
|
|
"redaction_policy": {
|
|
"policy_id": "pii-redaction",
|
|
"name": "PII Redaction",
|
|
"rules": [
|
|
{
|
|
"rule_id": "email-mask",
|
|
"field_pattern": "$.**.email",
|
|
"data_type": "email",
|
|
"action": "mask",
|
|
"preserve_chars": 3
|
|
},
|
|
{
|
|
"rule_id": "ip-hash",
|
|
"field_pattern": "$.**.ip_address",
|
|
"data_type": "ip_address",
|
|
"action": "hash",
|
|
"hash_algorithm": "sha256"
|
|
}
|
|
],
|
|
"default_action": "pass"
|
|
},
|
|
"retention_policy": {
|
|
"policy_id": "pii-retention",
|
|
"name": "PII Retention",
|
|
"default_retention_days": 90,
|
|
"rules": [
|
|
{
|
|
"data_type": "audit_logs",
|
|
"retention_days": 365,
|
|
"action_on_expiry": "archive"
|
|
}
|
|
]
|
|
},
|
|
"consent_required": true,
|
|
"audit_access": true
|
|
}
|
|
],
|
|
"debug_config": {
|
|
"enabled": true,
|
|
"opt_in_required": true,
|
|
"scopes_required": ["admin:*"],
|
|
"data_collected": [
|
|
{
|
|
"data_type": "request_traces",
|
|
"description": "HTTP request/response traces for debugging",
|
|
"retention_hours": 24
|
|
},
|
|
{
|
|
"data_type": "performance_metrics",
|
|
"description": "Detailed performance timing",
|
|
"retention_hours": 72
|
|
}
|
|
],
|
|
"redaction_applied": true
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|