Restructure solution layout by module
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				Docs CI / lint-and-preview (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	Docs CI / lint-and-preview (push) Has been cancelled
				
			This commit is contained in:
		| @@ -1,206 +1,206 @@ | ||||
| # StellaOps Authority configuration (dev profile) | ||||
| # Derived from etc/authority.yaml.sample; trimmed to the services needed for local | ||||
| # stacks and kept under version control so compose/helm bundles mount a working config. | ||||
|  | ||||
| schemaVersion: 1 | ||||
|  | ||||
| issuer: "https://authority.localtest.me" | ||||
|  | ||||
| accessTokenLifetime: "00:02:00" | ||||
| refreshTokenLifetime: "30.00:00:00" | ||||
| identityTokenLifetime: "00:05:00" | ||||
| authorizationCodeLifetime: "00:05:00" | ||||
| deviceCodeLifetime: "00:15:00" | ||||
|  | ||||
| storage: | ||||
|   connectionString: "mongodb://stellaops:stellaops@mongo:27017/stellaops_authority" | ||||
|   databaseName: "stellaops_authority" | ||||
|   commandTimeout: "00:00:30" | ||||
|  | ||||
| signing: | ||||
|   enabled: true | ||||
|   activeKeyId: "authority-signing-dev" | ||||
|   keyPath: "../certificates/authority-signing-dev.pem" | ||||
|   algorithm: "ES256" | ||||
|   keySource: "file" | ||||
|  | ||||
| bootstrap: | ||||
|   enabled: false | ||||
|   apiKey: "change-me" | ||||
|   defaultIdentityProvider: "standard" | ||||
|  | ||||
| pluginDirectories: | ||||
|   - "../StellaOps.Authority.PluginBinaries" | ||||
|  | ||||
| plugins: | ||||
|   configurationDirectory: "../etc/authority.plugins" | ||||
|   descriptors: | ||||
|     standard: | ||||
|       type: "standard" | ||||
|       assemblyName: "StellaOps.Authority.Plugin.Standard" | ||||
|       enabled: true | ||||
|       configFile: "standard.yaml" | ||||
|       capabilities: | ||||
|         - password | ||||
|         - bootstrap | ||||
|         - clientProvisioning | ||||
|       metadata: | ||||
|         defaultRole: "operators" | ||||
|  | ||||
| clients: | ||||
|   - clientId: "policy-engine" | ||||
|     displayName: "Policy Engine Service" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://policy-engine" ] | ||||
|     scopes: [ "policy:run", "findings:read", "effective:write" ] | ||||
|     tenant: "tenant-default" | ||||
|     properties: | ||||
|       serviceIdentity: "policy-engine" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/policy-engine.secret" | ||||
|  | ||||
|   - clientId: "policy-cli" | ||||
|     displayName: "Policy Automation CLI" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://policy-engine" ] | ||||
|     scopes: [ "policy:read", "policy:author", "policy:review", "policy:simulate", "findings:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/policy-cli.secret" | ||||
|  | ||||
|   - clientId: "cartographer-service" | ||||
|     displayName: "Cartographer Service" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://cartographer" ] | ||||
|     scopes: [ "graph:write", "graph:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     properties: | ||||
|       serviceIdentity: "cartographer" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/cartographer-service.secret" | ||||
|  | ||||
|   - clientId: "graph-api" | ||||
|     displayName: "Graph API Gateway" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://graph-api" ] | ||||
|     scopes: [ "graph:read", "graph:export", "graph:simulate" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/graph-api.secret" | ||||
|   - clientId: "export-center-operator" | ||||
|     displayName: "Export Center Operator" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://export-center" ] | ||||
|     scopes: [ "export.viewer", "export.operator" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/export-center-operator.secret" | ||||
|   - clientId: "export-center-admin" | ||||
|     displayName: "Export Center Admin" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://export-center" ] | ||||
|     scopes: [ "export.viewer", "export.operator", "export.admin" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/export-center-admin.secret" | ||||
|  | ||||
|   - clientId: "concelier-ingest" | ||||
|     displayName: "Concelier Ingestion" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://concelier" ] | ||||
|     scopes: [ "advisory:ingest", "advisory:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/concelier-ingest.secret" | ||||
|  | ||||
|   - clientId: "excitor-ingest" | ||||
|     displayName: "Excititor VEX Ingestion" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://excitor" ] | ||||
|     scopes: [ "vex:ingest", "vex:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/excitor-ingest.secret" | ||||
|  | ||||
|   - clientId: "graph-api-cli" | ||||
|     displayName: "Graph Explorer CLI" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://graph-api" ] | ||||
|     scopes: [ "graph:read", "graph:export" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/graph-api-cli.secret" | ||||
|  | ||||
| tenants: | ||||
|   - name: "tenant-default" | ||||
|     roles: | ||||
|       orch-viewer: | ||||
|         scopes: [ "orch:read" ] | ||||
|       orch-operator: | ||||
|         scopes: [ "orch:read", "orch:operate" ] | ||||
|       export-viewer: | ||||
|         scopes: [ "export.viewer" ] | ||||
|       export-operator: | ||||
|         scopes: [ "export.viewer", "export.operator" ] | ||||
|       export-admin: | ||||
|         scopes: [ "export.viewer", "export.operator", "export.admin" ] | ||||
|       policy-author: | ||||
|         scopes: [ "policy:author", "policy:read", "policy:simulate", "findings:read" ] | ||||
|       policy-reviewer: | ||||
|         scopes: [ "policy:review", "policy:read", "policy:simulate", "findings:read" ] | ||||
|       policy-approver: | ||||
|         scopes: [ "policy:approve", "policy:review", "policy:read", "policy:simulate", "findings:read" ] | ||||
|       policy-operator: | ||||
|         scopes: [ "policy:operate", "policy:run", "policy:activate", "policy:read", "policy:simulate", "findings:read" ] | ||||
|       policy-auditor: | ||||
|         scopes: [ "policy:audit", "policy:read", "policy:simulate", "findings:read" ] | ||||
|  | ||||
| security: | ||||
|   rateLimiting: | ||||
|     token: | ||||
|       enabled: true | ||||
|       permitLimit: 30 | ||||
|       window: "00:01:00" | ||||
|       queueLimit: 0 | ||||
|     authorize: | ||||
|       enabled: true | ||||
|       permitLimit: 60 | ||||
|       window: "00:01:00" | ||||
|       queueLimit: 10 | ||||
|   passwordHashing: | ||||
|     algorithm: "Argon2id" | ||||
|     memorySizeInKib: 19456 | ||||
|     iterations: 2 | ||||
|     parallelism: 1 | ||||
|   senderConstraints: | ||||
|     dpop: | ||||
|       enabled: true | ||||
|       proofLifetime: "00:05:00" | ||||
|       allowedClockSkew: "00:00:10" | ||||
|       replayWindow: "00:10:00" | ||||
|       nonce: | ||||
|         enabled: false | ||||
|     mtls: | ||||
|       enabled: false | ||||
|  | ||||
| bypassNetworks: | ||||
|   - "127.0.0.1/32" | ||||
|   - "::1/128" | ||||
| # StellaOps Authority configuration (dev profile) | ||||
| # Derived from etc/authority.yaml.sample; trimmed to the services needed for local | ||||
| # stacks and kept under version control so compose/helm bundles mount a working config. | ||||
|  | ||||
| schemaVersion: 1 | ||||
|  | ||||
| issuer: "https://authority.localtest.me" | ||||
|  | ||||
| accessTokenLifetime: "00:02:00" | ||||
| refreshTokenLifetime: "30.00:00:00" | ||||
| identityTokenLifetime: "00:05:00" | ||||
| authorizationCodeLifetime: "00:05:00" | ||||
| deviceCodeLifetime: "00:15:00" | ||||
|  | ||||
| storage: | ||||
|   connectionString: "mongodb://stellaops:stellaops@mongo:27017/stellaops_authority" | ||||
|   databaseName: "stellaops_authority" | ||||
|   commandTimeout: "00:00:30" | ||||
|  | ||||
| signing: | ||||
|   enabled: true | ||||
|   activeKeyId: "authority-signing-dev" | ||||
|   keyPath: "../certificates/authority-signing-dev.pem" | ||||
|   algorithm: "ES256" | ||||
|   keySource: "file" | ||||
|  | ||||
| bootstrap: | ||||
|   enabled: false | ||||
|   apiKey: "change-me" | ||||
|   defaultIdentityProvider: "standard" | ||||
|  | ||||
| pluginDirectories: | ||||
|   - "../StellaOps.Authority.PluginBinaries" | ||||
|  | ||||
| plugins: | ||||
|   configurationDirectory: "../etc/authority.plugins" | ||||
|   descriptors: | ||||
|     standard: | ||||
|       type: "standard" | ||||
|       assemblyName: "StellaOps.Authority.Plugin.Standard" | ||||
|       enabled: true | ||||
|       configFile: "standard.yaml" | ||||
|       capabilities: | ||||
|         - password | ||||
|         - bootstrap | ||||
|         - clientProvisioning | ||||
|       metadata: | ||||
|         defaultRole: "operators" | ||||
|  | ||||
| clients: | ||||
|   - clientId: "policy-engine" | ||||
|     displayName: "Policy Engine Service" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://policy-engine" ] | ||||
|     scopes: [ "policy:run", "findings:read", "effective:write" ] | ||||
|     tenant: "tenant-default" | ||||
|     properties: | ||||
|       serviceIdentity: "policy-engine" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/policy-engine.secret" | ||||
|  | ||||
|   - clientId: "policy-cli" | ||||
|     displayName: "Policy Automation CLI" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://policy-engine" ] | ||||
|     scopes: [ "policy:read", "policy:author", "policy:review", "policy:simulate", "findings:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/policy-cli.secret" | ||||
|  | ||||
|   - clientId: "cartographer-service" | ||||
|     displayName: "Cartographer Service" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://cartographer" ] | ||||
|     scopes: [ "graph:write", "graph:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     properties: | ||||
|       serviceIdentity: "cartographer" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/cartographer-service.secret" | ||||
|  | ||||
|   - clientId: "graph-api" | ||||
|     displayName: "Graph API Gateway" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://graph-api" ] | ||||
|     scopes: [ "graph:read", "graph:export", "graph:simulate" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/graph-api.secret" | ||||
|   - clientId: "export-center-operator" | ||||
|     displayName: "Export Center Operator" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://export-center" ] | ||||
|     scopes: [ "export.viewer", "export.operator" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/export-center-operator.secret" | ||||
|   - clientId: "export-center-admin" | ||||
|     displayName: "Export Center Admin" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://export-center" ] | ||||
|     scopes: [ "export.viewer", "export.operator", "export.admin" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/export-center-admin.secret" | ||||
|  | ||||
|   - clientId: "concelier-ingest" | ||||
|     displayName: "Concelier Ingestion" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://concelier" ] | ||||
|     scopes: [ "advisory:ingest", "advisory:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/concelier-ingest.secret" | ||||
|  | ||||
|   - clientId: "excitor-ingest" | ||||
|     displayName: "Excititor VEX Ingestion" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://excitor" ] | ||||
|     scopes: [ "vex:ingest", "vex:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/excitor-ingest.secret" | ||||
|  | ||||
|   - clientId: "graph-api-cli" | ||||
|     displayName: "Graph Explorer CLI" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://graph-api" ] | ||||
|     scopes: [ "graph:read", "graph:export" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/graph-api-cli.secret" | ||||
|  | ||||
| tenants: | ||||
|   - name: "tenant-default" | ||||
|     roles: | ||||
|       orch-viewer: | ||||
|         scopes: [ "orch:read" ] | ||||
|       orch-operator: | ||||
|         scopes: [ "orch:read", "orch:operate" ] | ||||
|       export-viewer: | ||||
|         scopes: [ "export.viewer" ] | ||||
|       export-operator: | ||||
|         scopes: [ "export.viewer", "export.operator" ] | ||||
|       export-admin: | ||||
|         scopes: [ "export.viewer", "export.operator", "export.admin" ] | ||||
|       policy-author: | ||||
|         scopes: [ "policy:author", "policy:read", "policy:simulate", "findings:read" ] | ||||
|       policy-reviewer: | ||||
|         scopes: [ "policy:review", "policy:read", "policy:simulate", "findings:read" ] | ||||
|       policy-approver: | ||||
|         scopes: [ "policy:approve", "policy:review", "policy:read", "policy:simulate", "findings:read" ] | ||||
|       policy-operator: | ||||
|         scopes: [ "policy:operate", "policy:run", "policy:activate", "policy:read", "policy:simulate", "findings:read" ] | ||||
|       policy-auditor: | ||||
|         scopes: [ "policy:audit", "policy:read", "policy:simulate", "findings:read" ] | ||||
|  | ||||
| security: | ||||
|   rateLimiting: | ||||
|     token: | ||||
|       enabled: true | ||||
|       permitLimit: 30 | ||||
|       window: "00:01:00" | ||||
|       queueLimit: 0 | ||||
|     authorize: | ||||
|       enabled: true | ||||
|       permitLimit: 60 | ||||
|       window: "00:01:00" | ||||
|       queueLimit: 10 | ||||
|   passwordHashing: | ||||
|     algorithm: "Argon2id" | ||||
|     memorySizeInKib: 19456 | ||||
|     iterations: 2 | ||||
|     parallelism: 1 | ||||
|   senderConstraints: | ||||
|     dpop: | ||||
|       enabled: true | ||||
|       proofLifetime: "00:05:00" | ||||
|       allowedClockSkew: "00:00:10" | ||||
|       replayWindow: "00:10:00" | ||||
|       nonce: | ||||
|         enabled: false | ||||
|     mtls: | ||||
|       enabled: false | ||||
|  | ||||
| bypassNetworks: | ||||
|   - "127.0.0.1/32" | ||||
|   - "::1/128" | ||||
|   | ||||
| @@ -1,337 +1,337 @@ | ||||
| # StellaOps Authority configuration template. | ||||
| # Copy to ../etc/authority.yaml (relative to the Authority content root) | ||||
| # and adjust values to fit your environment. Environment variables | ||||
| # prefixed with STELLAOPS_AUTHORITY_ override these values at runtime. | ||||
| # Example: STELLAOPS_AUTHORITY__ISSUER=https://authority.example.com | ||||
|  | ||||
| schemaVersion: 1 | ||||
|  | ||||
| # Absolute issuer URI advertised to clients. Use HTTPS for anything | ||||
| # beyond loopback development. | ||||
| issuer: "https://authority.stella-ops.local" | ||||
|  | ||||
| # Token lifetimes expressed as HH:MM:SS or DD.HH:MM:SS. | ||||
| accessTokenLifetime: "00:02:00" | ||||
| refreshTokenLifetime: "30.00:00:00" | ||||
| identityTokenLifetime: "00:05:00" | ||||
| authorizationCodeLifetime: "00:05:00" | ||||
| deviceCodeLifetime: "00:15:00" | ||||
|  | ||||
| # MongoDB storage connection details. | ||||
| storage: | ||||
|   connectionString: "mongodb://localhost:27017/stellaops-authority" | ||||
|   # databaseName: "stellaops_authority" | ||||
|   commandTimeout: "00:00:30" | ||||
|  | ||||
| # Signing configuration for revocation bundles and JWKS. | ||||
| signing: | ||||
|   enabled: true | ||||
|   activeKeyId: "authority-signing-2025-dev" | ||||
|   keyPath: "../certificates/authority-signing-2025-dev.pem" | ||||
|   algorithm: "ES256" | ||||
|   keySource: "file" | ||||
|   # provider: "default" | ||||
|   additionalKeys: | ||||
|     - keyId: "authority-signing-dev" | ||||
|       path: "../certificates/authority-signing-dev.pem" | ||||
|       source: "file" | ||||
|   # Rotation flow: | ||||
|   #   1. Generate a new PEM under ./certificates (e.g. authority-signing-2026-dev.pem). | ||||
|   #   2. Trigger the .gitea/workflows/authority-key-rotation.yml workflow (or run | ||||
|   #      ops/authority/key-rotation.sh) with the new keyId/keyPath. | ||||
|   #   3. Update activeKeyId/keyPath above and move the previous key into additionalKeys | ||||
|   #      so restarts retain retired material for JWKS consumers. | ||||
|  | ||||
| # Bootstrap administrative endpoints (initial provisioning). | ||||
| bootstrap: | ||||
|   enabled: false | ||||
|   apiKey: "change-me" | ||||
|   defaultIdentityProvider: "standard" | ||||
|  | ||||
| # Directories scanned for Authority plug-ins. Relative paths resolve | ||||
| # against the application content root, enabling air-gapped deployments | ||||
| # that package plug-ins alongside binaries. | ||||
| pluginDirectories: | ||||
|   - "../StellaOps.Authority.PluginBinaries" | ||||
|   # "/var/lib/stellaops/authority/plugins" | ||||
|  | ||||
| # Plug-in manifests live in descriptors below; per-plugin settings are stored | ||||
| # in the configurationDirectory (YAML files). Authority will load any enabled | ||||
| # plugins and surface their metadata/capabilities to the host. | ||||
| plugins: | ||||
|   configurationDirectory: "../etc/authority.plugins" | ||||
|   descriptors: | ||||
|     standard: | ||||
|       type: "standard" | ||||
|       assemblyName: "StellaOps.Authority.Plugin.Standard" | ||||
|       enabled: true | ||||
|       configFile: "standard.yaml" | ||||
|       capabilities: | ||||
|         - password | ||||
|         - bootstrap | ||||
|         - clientProvisioning | ||||
|       metadata: | ||||
|         defaultRole: "operators" | ||||
|     # Example for an external identity provider plugin. Leave disabled unless | ||||
|     # the plug-in package exists under StellaOps.Authority.PluginBinaries. | ||||
|     ldap: | ||||
|       type: "ldap" | ||||
|       assemblyName: "StellaOps.Authority.Plugin.Ldap" | ||||
|       enabled: false | ||||
|       configFile: "ldap.yaml" | ||||
|       capabilities: | ||||
|         - password | ||||
|         - mfa | ||||
|  | ||||
| # OAuth client registrations issued by Authority. These examples cover Notify WebService | ||||
| # in dev (notify.dev audience) and production (notify audience). Replace the secret files | ||||
| # with paths to your sealed credentials before enabling bootstrap mode. | ||||
| clients: | ||||
|   - clientId: "notify-web-dev" | ||||
|     displayName: "Notify WebService (dev)" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "notify.dev" ] | ||||
|     scopes: [ "notify.read", "notify.admin" ] | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/notify-web-dev.secret" | ||||
|   - clientId: "notify-web" | ||||
|     displayName: "Notify WebService" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "notify" ] | ||||
|     scopes: [ "notify.read", "notify.admin" ] | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/notify-web.secret" | ||||
|   - clientId: "concelier-ingest" | ||||
|     displayName: "Concelier Ingestion" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://concelier" ] | ||||
|     scopes: [ "advisory:ingest", "advisory:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/concelier-ingest.secret" | ||||
|   - clientId: "excitor-ingest" | ||||
|     displayName: "Excititor VEX Ingestion" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://excitor" ] | ||||
|     scopes: [ "vex:ingest", "vex:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/excitor-ingest.secret" | ||||
|   - clientId: "aoc-verifier" | ||||
|     displayName: "AOC Verification Agent" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://concelier", "api://excitor" ] | ||||
|     scopes: [ "aoc:verify", "advisory:read", "vex:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/aoc-verifier.secret" | ||||
|   - clientId: "policy-engine" | ||||
|     displayName: "Policy Engine Service" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://policy-engine" ] | ||||
|     scopes: [ "policy:run", "findings:read", "effective:write" ] | ||||
|     tenant: "tenant-default" | ||||
|     properties: | ||||
|       serviceIdentity: "policy-engine" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/policy-engine.secret" | ||||
|   - clientId: "policy-cli" | ||||
|     displayName: "Policy Automation CLI" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://policy-engine" ] | ||||
|     scopes: [ "policy:read", "policy:author", "policy:review", "policy:simulate", "findings:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/policy-cli.secret" | ||||
|   - clientId: "exceptions-service" | ||||
|     displayName: "Policy Engine Exceptions Worker" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://policy-engine" ] | ||||
|     scopes: [ "exceptions:read", "exceptions:write" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/exceptions-service.secret" | ||||
|   - clientId: "console-web" | ||||
|     displayName: "StellaOps Console" | ||||
|     grantTypes: [ "authorization_code", "refresh_token" ] | ||||
|     audiences: [ "console" ] | ||||
|     scopes: [ "openid", "profile", "email", "ui.read", "authority:tenants.read", "advisory:read", "vex:read", "exceptions:read", "exceptions:approve", "aoc:verify", "findings:read", "orch:read", "vuln:read" ] | ||||
|     # exceptions:approve is elevated via fresh-auth and requires an MFA-capable identity provider. | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     redirectUris: | ||||
|       - "https://console.stella-ops.local/oidc/callback" | ||||
|     postLogoutRedirectUris: | ||||
|       - "https://console.stella-ops.local/" | ||||
|     # Gateway must forward X-Stella-Tenant for /console endpoints; fresh-auth window (300s) | ||||
|     # returned by /console/profile governs admin actions in the Console UI. | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/console-web.secret" | ||||
|   - clientId: "cartographer-service" | ||||
|     displayName: "Cartographer Service" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://cartographer" ] | ||||
|     scopes: [ "graph:write", "graph:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     properties: | ||||
|       serviceIdentity: "cartographer" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/cartographer-service.secret" | ||||
|   - clientId: "graph-api" | ||||
|     displayName: "Graph API Gateway" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://graph-api" ] | ||||
|     scopes: [ "graph:read", "graph:export", "graph:simulate" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/graph-api.secret" | ||||
|   - clientId: "export-center-operator" | ||||
|     displayName: "Export Center Operator" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://export-center" ] | ||||
|     scopes: [ "export.viewer", "export.operator" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/export-center-operator.secret" | ||||
|   - clientId: "export-center-admin" | ||||
|     displayName: "Export Center Admin" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://export-center" ] | ||||
|     scopes: [ "export.viewer", "export.operator", "export.admin" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/export-center-admin.secret" | ||||
|   - clientId: "vuln-explorer-ui" | ||||
|     displayName: "Vuln Explorer UI" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://vuln-explorer" ] | ||||
|     scopes: [ "vuln:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/vuln-explorer-ui.secret" | ||||
|   # Signals sensors must request aoc:verify alongside write scope. | ||||
|   - clientId: "signals-uploader" | ||||
|     displayName: "Signals Sensor" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://signals" ] | ||||
|     scopes: [ "signals:write", "signals:read", "aoc:verify" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/signals-uploader.secret" | ||||
|  | ||||
| tenants: | ||||
|   - name: "tenant-default" | ||||
|     roles: | ||||
|       orch-viewer: | ||||
|         scopes: [ "orch:read" ] | ||||
|       orch-operator: | ||||
|         scopes: [ "orch:read", "orch:operate" ] | ||||
|       policy-author: | ||||
|         scopes: [ "policy:author", "policy:read", "policy:simulate", "findings:read" ] | ||||
|       policy-reviewer: | ||||
|         scopes: [ "policy:review", "policy:read", "policy:simulate", "findings:read" ] | ||||
|       policy-approver: | ||||
|         scopes: [ "policy:approve", "policy:review", "policy:read", "policy:simulate", "findings:read" ] | ||||
|       policy-operator: | ||||
|         scopes: [ "policy:operate", "policy:run", "policy:activate", "policy:read", "policy:simulate", "findings:read" ] | ||||
|       policy-auditor: | ||||
|         scopes: [ "policy:audit", "policy:read", "policy:simulate", "findings:read" ] | ||||
|       export-viewer: | ||||
|         scopes: [ "export.viewer" ] | ||||
|       export-operator: | ||||
|         scopes: [ "export.viewer", "export.operator" ] | ||||
|       export-admin: | ||||
|         scopes: [ "export.viewer", "export.operator", "export.admin" ] | ||||
|  | ||||
| # Exception approval routing templates used by Policy Engine and Console. | ||||
| exceptions: | ||||
|   routingTemplates: | ||||
|     - id: "secops" | ||||
|       authorityRouteId: "approvals/secops" | ||||
|       requireMfa: true | ||||
|       description: "Security Operations approval chain" | ||||
|     - id: "governance" | ||||
|       authorityRouteId: "approvals/governance" | ||||
|       requireMfa: false | ||||
|       description: "Governance review (non-production)" | ||||
|  | ||||
| # CIDR ranges that bypass network-sensitive policies (e.g. on-host cron jobs). | ||||
| # Keep the list tight: localhost is sufficient for most air-gapped installs. | ||||
| bypassNetworks: | ||||
|   - "127.0.0.1/32" | ||||
|   - "::1/128" | ||||
|  | ||||
| # Security posture (rate limiting + sender constraints). | ||||
| security: | ||||
|   rateLimiting: | ||||
|     token: | ||||
|       enabled: true | ||||
|       permitLimit: 30 | ||||
|       window: "00:01:00" | ||||
|       queueLimit: 0 | ||||
|     authorize: | ||||
|       enabled: true | ||||
|       permitLimit: 60 | ||||
|       window: "00:01:00" | ||||
|       queueLimit: 10 | ||||
|     internal: | ||||
|       enabled: false | ||||
|       permitLimit: 5 | ||||
|       window: "00:01:00" | ||||
|       queueLimit: 0 | ||||
|   senderConstraints: | ||||
|     dpop: | ||||
|       enabled: true | ||||
|       allowedAlgorithms: [ "ES256", "ES384" ] | ||||
|       proofLifetime: "00:02:00" | ||||
|       allowedClockSkew: "00:00:30" | ||||
|       replayWindow: "00:05:00" | ||||
|       nonce: | ||||
|         enabled: true | ||||
|         ttl: "00:10:00" | ||||
|         maxIssuancePerMinute: 120 | ||||
|         store: "memory" # Set to "redis" for multi-node Authority deployments. | ||||
|         requiredAudiences: | ||||
|           - "signer" | ||||
|           - "attestor" | ||||
|         # redisConnectionString: "redis://authority-redis:6379?ssl=false" | ||||
|     mtls: | ||||
|       enabled: false | ||||
|       requireChainValidation: true | ||||
|       rotationGrace: "00:15:00" | ||||
|       enforceForAudiences: | ||||
|         - "signer" # Requests for these audiences force mTLS sender constraints | ||||
|       allowedSanTypes: | ||||
|         - "dns" | ||||
|         - "uri" | ||||
|       allowedCertificateAuthorities: [ ] | ||||
|       allowedSubjectPatterns: [ ] | ||||
| # StellaOps Authority configuration template. | ||||
| # Copy to ../etc/authority.yaml (relative to the Authority content root) | ||||
| # and adjust values to fit your environment. Environment variables | ||||
| # prefixed with STELLAOPS_AUTHORITY_ override these values at runtime. | ||||
| # Example: STELLAOPS_AUTHORITY__ISSUER=https://authority.example.com | ||||
|  | ||||
| schemaVersion: 1 | ||||
|  | ||||
| # Absolute issuer URI advertised to clients. Use HTTPS for anything | ||||
| # beyond loopback development. | ||||
| issuer: "https://authority.stella-ops.local" | ||||
|  | ||||
| # Token lifetimes expressed as HH:MM:SS or DD.HH:MM:SS. | ||||
| accessTokenLifetime: "00:02:00" | ||||
| refreshTokenLifetime: "30.00:00:00" | ||||
| identityTokenLifetime: "00:05:00" | ||||
| authorizationCodeLifetime: "00:05:00" | ||||
| deviceCodeLifetime: "00:15:00" | ||||
|  | ||||
| # MongoDB storage connection details. | ||||
| storage: | ||||
|   connectionString: "mongodb://localhost:27017/stellaops-authority" | ||||
|   # databaseName: "stellaops_authority" | ||||
|   commandTimeout: "00:00:30" | ||||
|  | ||||
| # Signing configuration for revocation bundles and JWKS. | ||||
| signing: | ||||
|   enabled: true | ||||
|   activeKeyId: "authority-signing-2025-dev" | ||||
|   keyPath: "../certificates/authority-signing-2025-dev.pem" | ||||
|   algorithm: "ES256" | ||||
|   keySource: "file" | ||||
|   # provider: "default" | ||||
|   additionalKeys: | ||||
|     - keyId: "authority-signing-dev" | ||||
|       path: "../certificates/authority-signing-dev.pem" | ||||
|       source: "file" | ||||
|   # Rotation flow: | ||||
|   #   1. Generate a new PEM under ./certificates (e.g. authority-signing-2026-dev.pem). | ||||
|   #   2. Trigger the .gitea/workflows/authority-key-rotation.yml workflow (or run | ||||
|   #      ops/authority/key-rotation.sh) with the new keyId/keyPath. | ||||
|   #   3. Update activeKeyId/keyPath above and move the previous key into additionalKeys | ||||
|   #      so restarts retain retired material for JWKS consumers. | ||||
|  | ||||
| # Bootstrap administrative endpoints (initial provisioning). | ||||
| bootstrap: | ||||
|   enabled: false | ||||
|   apiKey: "change-me" | ||||
|   defaultIdentityProvider: "standard" | ||||
|  | ||||
| # Directories scanned for Authority plug-ins. Relative paths resolve | ||||
| # against the application content root, enabling air-gapped deployments | ||||
| # that package plug-ins alongside binaries. | ||||
| pluginDirectories: | ||||
|   - "../StellaOps.Authority.PluginBinaries" | ||||
|   # "/var/lib/stellaops/authority/plugins" | ||||
|  | ||||
| # Plug-in manifests live in descriptors below; per-plugin settings are stored | ||||
| # in the configurationDirectory (YAML files). Authority will load any enabled | ||||
| # plugins and surface their metadata/capabilities to the host. | ||||
| plugins: | ||||
|   configurationDirectory: "../etc/authority.plugins" | ||||
|   descriptors: | ||||
|     standard: | ||||
|       type: "standard" | ||||
|       assemblyName: "StellaOps.Authority.Plugin.Standard" | ||||
|       enabled: true | ||||
|       configFile: "standard.yaml" | ||||
|       capabilities: | ||||
|         - password | ||||
|         - bootstrap | ||||
|         - clientProvisioning | ||||
|       metadata: | ||||
|         defaultRole: "operators" | ||||
|     # Example for an external identity provider plugin. Leave disabled unless | ||||
|     # the plug-in package exists under StellaOps.Authority.PluginBinaries. | ||||
|     ldap: | ||||
|       type: "ldap" | ||||
|       assemblyName: "StellaOps.Authority.Plugin.Ldap" | ||||
|       enabled: false | ||||
|       configFile: "ldap.yaml" | ||||
|       capabilities: | ||||
|         - password | ||||
|         - mfa | ||||
|  | ||||
| # OAuth client registrations issued by Authority. These examples cover Notify WebService | ||||
| # in dev (notify.dev audience) and production (notify audience). Replace the secret files | ||||
| # with paths to your sealed credentials before enabling bootstrap mode. | ||||
| clients: | ||||
|   - clientId: "notify-web-dev" | ||||
|     displayName: "Notify WebService (dev)" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "notify.dev" ] | ||||
|     scopes: [ "notify.read", "notify.admin" ] | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/notify-web-dev.secret" | ||||
|   - clientId: "notify-web" | ||||
|     displayName: "Notify WebService" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "notify" ] | ||||
|     scopes: [ "notify.read", "notify.admin" ] | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/notify-web.secret" | ||||
|   - clientId: "concelier-ingest" | ||||
|     displayName: "Concelier Ingestion" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://concelier" ] | ||||
|     scopes: [ "advisory:ingest", "advisory:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/concelier-ingest.secret" | ||||
|   - clientId: "excitor-ingest" | ||||
|     displayName: "Excititor VEX Ingestion" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://excitor" ] | ||||
|     scopes: [ "vex:ingest", "vex:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/excitor-ingest.secret" | ||||
|   - clientId: "aoc-verifier" | ||||
|     displayName: "AOC Verification Agent" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://concelier", "api://excitor" ] | ||||
|     scopes: [ "aoc:verify", "advisory:read", "vex:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/aoc-verifier.secret" | ||||
|   - clientId: "policy-engine" | ||||
|     displayName: "Policy Engine Service" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://policy-engine" ] | ||||
|     scopes: [ "policy:run", "findings:read", "effective:write" ] | ||||
|     tenant: "tenant-default" | ||||
|     properties: | ||||
|       serviceIdentity: "policy-engine" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/policy-engine.secret" | ||||
|   - clientId: "policy-cli" | ||||
|     displayName: "Policy Automation CLI" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://policy-engine" ] | ||||
|     scopes: [ "policy:read", "policy:author", "policy:review", "policy:simulate", "findings:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/policy-cli.secret" | ||||
|   - clientId: "exceptions-service" | ||||
|     displayName: "Policy Engine Exceptions Worker" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://policy-engine" ] | ||||
|     scopes: [ "exceptions:read", "exceptions:write" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/exceptions-service.secret" | ||||
|   - clientId: "console-web" | ||||
|     displayName: "StellaOps Console" | ||||
|     grantTypes: [ "authorization_code", "refresh_token" ] | ||||
|     audiences: [ "console" ] | ||||
|     scopes: [ "openid", "profile", "email", "ui.read", "authority:tenants.read", "advisory:read", "vex:read", "exceptions:read", "exceptions:approve", "aoc:verify", "findings:read", "orch:read", "vuln:read" ] | ||||
|     # exceptions:approve is elevated via fresh-auth and requires an MFA-capable identity provider. | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     redirectUris: | ||||
|       - "https://console.stella-ops.local/oidc/callback" | ||||
|     postLogoutRedirectUris: | ||||
|       - "https://console.stella-ops.local/" | ||||
|     # Gateway must forward X-Stella-Tenant for /console endpoints; fresh-auth window (300s) | ||||
|     # returned by /console/profile governs admin actions in the Console UI. | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/console-web.secret" | ||||
|   - clientId: "cartographer-service" | ||||
|     displayName: "Cartographer Service" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://cartographer" ] | ||||
|     scopes: [ "graph:write", "graph:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     properties: | ||||
|       serviceIdentity: "cartographer" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/cartographer-service.secret" | ||||
|   - clientId: "graph-api" | ||||
|     displayName: "Graph API Gateway" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://graph-api" ] | ||||
|     scopes: [ "graph:read", "graph:export", "graph:simulate" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/graph-api.secret" | ||||
|   - clientId: "export-center-operator" | ||||
|     displayName: "Export Center Operator" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://export-center" ] | ||||
|     scopes: [ "export.viewer", "export.operator" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/export-center-operator.secret" | ||||
|   - clientId: "export-center-admin" | ||||
|     displayName: "Export Center Admin" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://export-center" ] | ||||
|     scopes: [ "export.viewer", "export.operator", "export.admin" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/export-center-admin.secret" | ||||
|   - clientId: "vuln-explorer-ui" | ||||
|     displayName: "Vuln Explorer UI" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://vuln-explorer" ] | ||||
|     scopes: [ "vuln:read" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/vuln-explorer-ui.secret" | ||||
|   # Signals sensors must request aoc:verify alongside write scope. | ||||
|   - clientId: "signals-uploader" | ||||
|     displayName: "Signals Sensor" | ||||
|     grantTypes: [ "client_credentials" ] | ||||
|     audiences: [ "api://signals" ] | ||||
|     scopes: [ "signals:write", "signals:read", "aoc:verify" ] | ||||
|     tenant: "tenant-default" | ||||
|     senderConstraint: "dpop" | ||||
|     auth: | ||||
|       type: "client_secret" | ||||
|       secretFile: "../secrets/signals-uploader.secret" | ||||
|  | ||||
| tenants: | ||||
|   - name: "tenant-default" | ||||
|     roles: | ||||
|       orch-viewer: | ||||
|         scopes: [ "orch:read" ] | ||||
|       orch-operator: | ||||
|         scopes: [ "orch:read", "orch:operate" ] | ||||
|       policy-author: | ||||
|         scopes: [ "policy:author", "policy:read", "policy:simulate", "findings:read" ] | ||||
|       policy-reviewer: | ||||
|         scopes: [ "policy:review", "policy:read", "policy:simulate", "findings:read" ] | ||||
|       policy-approver: | ||||
|         scopes: [ "policy:approve", "policy:review", "policy:read", "policy:simulate", "findings:read" ] | ||||
|       policy-operator: | ||||
|         scopes: [ "policy:operate", "policy:run", "policy:activate", "policy:read", "policy:simulate", "findings:read" ] | ||||
|       policy-auditor: | ||||
|         scopes: [ "policy:audit", "policy:read", "policy:simulate", "findings:read" ] | ||||
|       export-viewer: | ||||
|         scopes: [ "export.viewer" ] | ||||
|       export-operator: | ||||
|         scopes: [ "export.viewer", "export.operator" ] | ||||
|       export-admin: | ||||
|         scopes: [ "export.viewer", "export.operator", "export.admin" ] | ||||
|  | ||||
| # Exception approval routing templates used by Policy Engine and Console. | ||||
| exceptions: | ||||
|   routingTemplates: | ||||
|     - id: "secops" | ||||
|       authorityRouteId: "approvals/secops" | ||||
|       requireMfa: true | ||||
|       description: "Security Operations approval chain" | ||||
|     - id: "governance" | ||||
|       authorityRouteId: "approvals/governance" | ||||
|       requireMfa: false | ||||
|       description: "Governance review (non-production)" | ||||
|  | ||||
| # CIDR ranges that bypass network-sensitive policies (e.g. on-host cron jobs). | ||||
| # Keep the list tight: localhost is sufficient for most air-gapped installs. | ||||
| bypassNetworks: | ||||
|   - "127.0.0.1/32" | ||||
|   - "::1/128" | ||||
|  | ||||
| # Security posture (rate limiting + sender constraints). | ||||
| security: | ||||
|   rateLimiting: | ||||
|     token: | ||||
|       enabled: true | ||||
|       permitLimit: 30 | ||||
|       window: "00:01:00" | ||||
|       queueLimit: 0 | ||||
|     authorize: | ||||
|       enabled: true | ||||
|       permitLimit: 60 | ||||
|       window: "00:01:00" | ||||
|       queueLimit: 10 | ||||
|     internal: | ||||
|       enabled: false | ||||
|       permitLimit: 5 | ||||
|       window: "00:01:00" | ||||
|       queueLimit: 0 | ||||
|   senderConstraints: | ||||
|     dpop: | ||||
|       enabled: true | ||||
|       allowedAlgorithms: [ "ES256", "ES384" ] | ||||
|       proofLifetime: "00:02:00" | ||||
|       allowedClockSkew: "00:00:30" | ||||
|       replayWindow: "00:05:00" | ||||
|       nonce: | ||||
|         enabled: true | ||||
|         ttl: "00:10:00" | ||||
|         maxIssuancePerMinute: 120 | ||||
|         store: "memory" # Set to "redis" for multi-node Authority deployments. | ||||
|         requiredAudiences: | ||||
|           - "signer" | ||||
|           - "attestor" | ||||
|         # redisConnectionString: "redis://authority-redis:6379?ssl=false" | ||||
|     mtls: | ||||
|       enabled: false | ||||
|       requireChainValidation: true | ||||
|       rotationGrace: "00:15:00" | ||||
|       enforceForAudiences: | ||||
|         - "signer" # Requests for these audiences force mTLS sender constraints | ||||
|       allowedSanTypes: | ||||
|         - "dns" | ||||
|         - "uri" | ||||
|       allowedCertificateAuthorities: [ ] | ||||
|       allowedSubjectPatterns: [ ] | ||||
|   | ||||
| @@ -1,119 +1,119 @@ | ||||
| # Concelier configuration template for StellaOps deployments. | ||||
| # Copy to ../etc/concelier.yaml (relative to the web service content root) | ||||
| # and adjust the values to match your environment. Environment variables | ||||
| # (prefixed with CONCELIER_) override these settings at runtime. | ||||
|  | ||||
| storage: | ||||
|   driver: mongo | ||||
|   # Mongo connection string. Use SRV URI or standard connection string. | ||||
|   dsn: "mongodb://concelier:concelier@mongo:27017/concelier?authSource=admin" | ||||
|   # Optional database name; defaults to the name embedded in the DSN or 'concelier'. | ||||
|   database: "concelier" | ||||
|   # Mongo command timeout in seconds. | ||||
|   commandTimeoutSeconds: 30 | ||||
|  | ||||
| plugins: | ||||
|   # Concelier resolves plug-ins relative to the content root; override as needed. | ||||
|   baseDirectory: ".." | ||||
|   directory: "StellaOps.Concelier.PluginBinaries" | ||||
|   searchPatterns: | ||||
|     - "StellaOps.Concelier.Plugin.*.dll" | ||||
|  | ||||
| telemetry: | ||||
|   enabled: true | ||||
|   enableTracing: false | ||||
|   enableMetrics: false | ||||
|   enableLogging: true | ||||
|   minimumLogLevel: "Information" | ||||
|   serviceName: "stellaops-concelier" | ||||
|   # Configure OTLP endpoint when shipping traces/metrics/logs out-of-band. | ||||
|   otlpEndpoint: "" | ||||
|   # Optional headers for OTLP exporters, for example authentication tokens. | ||||
|   otlpHeaders: {} | ||||
|   # Attach additional resource attributes to telemetry exports. | ||||
|   resourceAttributes: | ||||
|     deployment.environment: "local" | ||||
|   # Emit console exporters for local debugging. | ||||
|   exportConsole: true | ||||
|  | ||||
| authority: | ||||
|   enabled: false | ||||
|   # Temporary rollout flag. When true, Concelier logs anonymous access but does not fail requests | ||||
|   # without tokens. Set to false before 2025-12-31 UTC to enforce authentication fully. | ||||
|   allowAnonymousFallback: true | ||||
|   # Issuer advertised by StellaOps Authority (e.g. https://authority.stella-ops.local). | ||||
|   issuer: "https://authority.stella-ops.local" | ||||
|   # Optional explicit metadata address; defaults to {issuer}/.well-known/openid-configuration. | ||||
|   metadataAddress: "" | ||||
|   requireHttpsMetadata: true | ||||
|   backchannelTimeoutSeconds: 30 | ||||
|   tokenClockSkewSeconds: 60 | ||||
|   audiences: | ||||
|     - "api://concelier" | ||||
|   requiredScopes: | ||||
|     - "concelier.jobs.trigger" | ||||
|     - "advisory:read" | ||||
|     - "advisory:ingest" | ||||
|   requiredTenants: | ||||
|     - "tenant-default" | ||||
|   # Outbound credentials Concelier can use to call Authority (client credentials flow). | ||||
|   clientId: "concelier-jobs" | ||||
|   # Prefer storing the secret outside of the config file. Provide either clientSecret or clientSecretFile. | ||||
|   clientSecret: "" | ||||
|   clientSecretFile: "" | ||||
|   clientScopes: | ||||
|     - "concelier.jobs.trigger" | ||||
|     - "advisory:read" | ||||
|     - "advisory:ingest" | ||||
|   resilience: | ||||
|     # Enable deterministic retry/backoff when Authority is briefly unavailable. | ||||
|     enableRetries: true | ||||
|     retryDelays: | ||||
|       - "00:00:01" | ||||
|       - "00:00:02" | ||||
|       - "00:00:05" | ||||
|     # Allow stale discovery/JWKS responses when Authority is offline (extend tolerance as needed for air-gapped mirrors). | ||||
|     allowOfflineCacheFallback: true | ||||
|     offlineCacheTolerance: "00:10:00" | ||||
|   # Networks allowed to bypass authentication (loopback by default for on-host cron jobs). | ||||
|   bypassNetworks: | ||||
|     - "127.0.0.1/32" | ||||
|     - "::1/128" | ||||
|  | ||||
| mirror: | ||||
|   enabled: false | ||||
|   # Directory containing JSON exporter outputs (absolute or relative to content root). | ||||
|   exportRoot: "exports/json" | ||||
|   # Optional explicit export identifier; defaults to `latest` symlink or most recent export. | ||||
|   activeExportId: "" | ||||
|   latestDirectoryName: "latest" | ||||
|   mirrorDirectoryName: "mirror" | ||||
|   requireAuthentication: false | ||||
|   maxIndexRequestsPerHour: 600 | ||||
|   domains: | ||||
|     - id: "primary" | ||||
|       displayName: "Primary Mirror" | ||||
|       requireAuthentication: false | ||||
|       maxDownloadRequestsPerHour: 1200 | ||||
|  | ||||
| sources: | ||||
|   ghsa: | ||||
|     apiToken: "${GITHUB_PAT}" | ||||
|     pageSize: 50 | ||||
|     maxPagesPerFetch: 5 | ||||
|     requestDelay: "00:00:00.200" | ||||
|     failureBackoff: "00:05:00" | ||||
|     rateLimitWarningThreshold: 500 | ||||
|     secondaryRateLimitBackoff: "00:02:00" | ||||
|   cve: | ||||
|     baseEndpoint: "https://cveawg.mitre.org/api/" | ||||
|     apiOrg: "" | ||||
|     apiUser: "" | ||||
|     apiKey: "" | ||||
|     # Optional mirror used when credentials are unavailable. | ||||
|     seedDirectory: "./seed-data/cve" | ||||
|     pageSize: 200 | ||||
|     maxPagesPerFetch: 5 | ||||
|     initialBackfill: "30.00:00:00" | ||||
|     requestDelay: "00:00:00.250" | ||||
|     failureBackoff: "00:10:00" | ||||
| # Concelier configuration template for StellaOps deployments. | ||||
| # Copy to ../etc/concelier.yaml (relative to the web service content root) | ||||
| # and adjust the values to match your environment. Environment variables | ||||
| # (prefixed with CONCELIER_) override these settings at runtime. | ||||
|  | ||||
| storage: | ||||
|   driver: mongo | ||||
|   # Mongo connection string. Use SRV URI or standard connection string. | ||||
|   dsn: "mongodb://concelier:concelier@mongo:27017/concelier?authSource=admin" | ||||
|   # Optional database name; defaults to the name embedded in the DSN or 'concelier'. | ||||
|   database: "concelier" | ||||
|   # Mongo command timeout in seconds. | ||||
|   commandTimeoutSeconds: 30 | ||||
|  | ||||
| plugins: | ||||
|   # Concelier resolves plug-ins relative to the content root; override as needed. | ||||
|   baseDirectory: ".." | ||||
|   directory: "StellaOps.Concelier.PluginBinaries" | ||||
|   searchPatterns: | ||||
|     - "StellaOps.Concelier.Plugin.*.dll" | ||||
|  | ||||
| telemetry: | ||||
|   enabled: true | ||||
|   enableTracing: false | ||||
|   enableMetrics: false | ||||
|   enableLogging: true | ||||
|   minimumLogLevel: "Information" | ||||
|   serviceName: "stellaops-concelier" | ||||
|   # Configure OTLP endpoint when shipping traces/metrics/logs out-of-band. | ||||
|   otlpEndpoint: "" | ||||
|   # Optional headers for OTLP exporters, for example authentication tokens. | ||||
|   otlpHeaders: {} | ||||
|   # Attach additional resource attributes to telemetry exports. | ||||
|   resourceAttributes: | ||||
|     deployment.environment: "local" | ||||
|   # Emit console exporters for local debugging. | ||||
|   exportConsole: true | ||||
|  | ||||
| authority: | ||||
|   enabled: false | ||||
|   # Temporary rollout flag. When true, Concelier logs anonymous access but does not fail requests | ||||
|   # without tokens. Set to false before 2025-12-31 UTC to enforce authentication fully. | ||||
|   allowAnonymousFallback: true | ||||
|   # Issuer advertised by StellaOps Authority (e.g. https://authority.stella-ops.local). | ||||
|   issuer: "https://authority.stella-ops.local" | ||||
|   # Optional explicit metadata address; defaults to {issuer}/.well-known/openid-configuration. | ||||
|   metadataAddress: "" | ||||
|   requireHttpsMetadata: true | ||||
|   backchannelTimeoutSeconds: 30 | ||||
|   tokenClockSkewSeconds: 60 | ||||
|   audiences: | ||||
|     - "api://concelier" | ||||
|   requiredScopes: | ||||
|     - "concelier.jobs.trigger" | ||||
|     - "advisory:read" | ||||
|     - "advisory:ingest" | ||||
|   requiredTenants: | ||||
|     - "tenant-default" | ||||
|   # Outbound credentials Concelier can use to call Authority (client credentials flow). | ||||
|   clientId: "concelier-jobs" | ||||
|   # Prefer storing the secret outside of the config file. Provide either clientSecret or clientSecretFile. | ||||
|   clientSecret: "" | ||||
|   clientSecretFile: "" | ||||
|   clientScopes: | ||||
|     - "concelier.jobs.trigger" | ||||
|     - "advisory:read" | ||||
|     - "advisory:ingest" | ||||
|   resilience: | ||||
|     # Enable deterministic retry/backoff when Authority is briefly unavailable. | ||||
|     enableRetries: true | ||||
|     retryDelays: | ||||
|       - "00:00:01" | ||||
|       - "00:00:02" | ||||
|       - "00:00:05" | ||||
|     # Allow stale discovery/JWKS responses when Authority is offline (extend tolerance as needed for air-gapped mirrors). | ||||
|     allowOfflineCacheFallback: true | ||||
|     offlineCacheTolerance: "00:10:00" | ||||
|   # Networks allowed to bypass authentication (loopback by default for on-host cron jobs). | ||||
|   bypassNetworks: | ||||
|     - "127.0.0.1/32" | ||||
|     - "::1/128" | ||||
|  | ||||
| mirror: | ||||
|   enabled: false | ||||
|   # Directory containing JSON exporter outputs (absolute or relative to content root). | ||||
|   exportRoot: "exports/json" | ||||
|   # Optional explicit export identifier; defaults to `latest` symlink or most recent export. | ||||
|   activeExportId: "" | ||||
|   latestDirectoryName: "latest" | ||||
|   mirrorDirectoryName: "mirror" | ||||
|   requireAuthentication: false | ||||
|   maxIndexRequestsPerHour: 600 | ||||
|   domains: | ||||
|     - id: "primary" | ||||
|       displayName: "Primary Mirror" | ||||
|       requireAuthentication: false | ||||
|       maxDownloadRequestsPerHour: 1200 | ||||
|  | ||||
| sources: | ||||
|   ghsa: | ||||
|     apiToken: "${GITHUB_PAT}" | ||||
|     pageSize: 50 | ||||
|     maxPagesPerFetch: 5 | ||||
|     requestDelay: "00:00:00.200" | ||||
|     failureBackoff: "00:05:00" | ||||
|     rateLimitWarningThreshold: 500 | ||||
|     secondaryRateLimitBackoff: "00:02:00" | ||||
|   cve: | ||||
|     baseEndpoint: "https://cveawg.mitre.org/api/" | ||||
|     apiOrg: "" | ||||
|     apiUser: "" | ||||
|     apiKey: "" | ||||
|     # Optional mirror used when credentials are unavailable. | ||||
|     seedDirectory: "./seed-data/cve" | ||||
|     pageSize: 200 | ||||
|     maxPagesPerFetch: 5 | ||||
|     initialBackfill: "30.00:00:00" | ||||
|     requestDelay: "00:00:00.250" | ||||
|     failureBackoff: "00:10:00" | ||||
|   | ||||
| @@ -1,33 +1,33 @@ | ||||
| # StellaOps Policy Engine configuration template. | ||||
| # Copy to ../etc/policy-engine.yaml (relative to the Policy Engine content root) | ||||
| # and adjust values to fit your environment. Environment variables prefixed with | ||||
| # STELLAOPS_POLICY_ENGINE_ override these values at runtime. | ||||
|  | ||||
| schemaVersion: 1 | ||||
|  | ||||
| authority: | ||||
|   enabled: true | ||||
|   issuer: "https://authority.stella-ops.local" | ||||
|   clientId: "policy-engine" | ||||
|   clientSecret: "change-me" | ||||
|   scopes: [ "policy:run", "findings:read", "effective:write" ] | ||||
|   backchannelTimeoutSeconds: 30 | ||||
|  | ||||
| storage: | ||||
|   connectionString: "mongodb://localhost:27017/policy-engine" | ||||
|   databaseName: "policy_engine" | ||||
|   commandTimeoutSeconds: 30 | ||||
|  | ||||
| workers: | ||||
|   schedulerIntervalSeconds: 15 | ||||
|   maxConcurrentEvaluations: 4 | ||||
|  | ||||
| resourceServer: | ||||
|   authority: "https://authority.stella-ops.local" | ||||
|   requireHttpsMetadata: true | ||||
|   audiences: [ "api://policy-engine" ] | ||||
|   requiredScopes: [ "policy:run" ] | ||||
|   requiredTenants: [ ] | ||||
|   bypassNetworks: | ||||
|     - "127.0.0.1/32" | ||||
|     - "::1/128" | ||||
| # StellaOps Policy Engine configuration template. | ||||
| # Copy to ../etc/policy-engine.yaml (relative to the Policy Engine content root) | ||||
| # and adjust values to fit your environment. Environment variables prefixed with | ||||
| # STELLAOPS_POLICY_ENGINE_ override these values at runtime. | ||||
|  | ||||
| schemaVersion: 1 | ||||
|  | ||||
| authority: | ||||
|   enabled: true | ||||
|   issuer: "https://authority.stella-ops.local" | ||||
|   clientId: "policy-engine" | ||||
|   clientSecret: "change-me" | ||||
|   scopes: [ "policy:run", "findings:read", "effective:write" ] | ||||
|   backchannelTimeoutSeconds: 30 | ||||
|  | ||||
| storage: | ||||
|   connectionString: "mongodb://localhost:27017/policy-engine" | ||||
|   databaseName: "policy_engine" | ||||
|   commandTimeoutSeconds: 30 | ||||
|  | ||||
| workers: | ||||
|   schedulerIntervalSeconds: 15 | ||||
|   maxConcurrentEvaluations: 4 | ||||
|  | ||||
| resourceServer: | ||||
|   authority: "https://authority.stella-ops.local" | ||||
|   requireHttpsMetadata: true | ||||
|   audiences: [ "api://policy-engine" ] | ||||
|   requiredScopes: [ "policy:run" ] | ||||
|   requiredTenants: [ ] | ||||
|   bypassNetworks: | ||||
|     - "127.0.0.1/32" | ||||
|     - "::1/128" | ||||
|   | ||||
| @@ -1,39 +1,39 @@ | ||||
| # StellaOps Policy Gateway configuration template. | ||||
| # Copy to ../etc/policy-gateway.yaml (relative to the gateway content root) | ||||
| # and adjust values to fit your environment. Environment variables prefixed with | ||||
| # STELLAOPS_POLICY_GATEWAY_ override these values at runtime. | ||||
|  | ||||
| schemaVersion: 1 | ||||
|  | ||||
| telemetry: | ||||
|   minimumLogLevel: Information | ||||
|  | ||||
| resourceServer: | ||||
|   authority: "https://authority.stella-ops.local" | ||||
|   metadataAddress: "https://authority.stella-ops.local/.well-known/openid-configuration" | ||||
|   audiences: [ "api://policy-gateway" ] | ||||
|   requiredScopes: [ "policy:read", "policy:author", "policy:review", "policy:approve", "policy:operate", "policy:simulate", "policy:run", "policy:activate" ] | ||||
|   requiredTenants: [ ] | ||||
|   bypassNetworks: | ||||
|     - "127.0.0.1/32" | ||||
|     - "::1/128" | ||||
|   requireHttpsMetadata: true | ||||
|   backchannelTimeoutSeconds: 30 | ||||
|   tokenClockSkewSeconds: 60 | ||||
|  | ||||
| policyEngine: | ||||
|   baseAddress: "https://policy-engine.stella-ops.local" | ||||
|   audience: "api://policy-engine" | ||||
|   clientCredentials: | ||||
|     enabled: true | ||||
|     clientId: "policy-gateway" | ||||
|     clientSecret: "change-me" | ||||
|     scopes: [ "policy:read", "policy:author", "policy:review", "policy:approve", "policy:operate", "policy:simulate", "policy:run", "policy:activate" ] | ||||
|     backchannelTimeoutSeconds: 30 | ||||
|   dpop: | ||||
|     enabled: false | ||||
|     keyPath: "../etc/policy-gateway-dpop.pem" | ||||
|     keyPassphrase: "" | ||||
|     algorithm: "ES256" | ||||
|     proofLifetime: "00:02:00" | ||||
|     clockSkew: "00:00:30" | ||||
| # StellaOps Policy Gateway configuration template. | ||||
| # Copy to ../etc/policy-gateway.yaml (relative to the gateway content root) | ||||
| # and adjust values to fit your environment. Environment variables prefixed with | ||||
| # STELLAOPS_POLICY_GATEWAY_ override these values at runtime. | ||||
|  | ||||
| schemaVersion: 1 | ||||
|  | ||||
| telemetry: | ||||
|   minimumLogLevel: Information | ||||
|  | ||||
| resourceServer: | ||||
|   authority: "https://authority.stella-ops.local" | ||||
|   metadataAddress: "https://authority.stella-ops.local/.well-known/openid-configuration" | ||||
|   audiences: [ "api://policy-gateway" ] | ||||
|   requiredScopes: [ "policy:read", "policy:author", "policy:review", "policy:approve", "policy:operate", "policy:simulate", "policy:run", "policy:activate" ] | ||||
|   requiredTenants: [ ] | ||||
|   bypassNetworks: | ||||
|     - "127.0.0.1/32" | ||||
|     - "::1/128" | ||||
|   requireHttpsMetadata: true | ||||
|   backchannelTimeoutSeconds: 30 | ||||
|   tokenClockSkewSeconds: 60 | ||||
|  | ||||
| policyEngine: | ||||
|   baseAddress: "https://policy-engine.stella-ops.local" | ||||
|   audience: "api://policy-engine" | ||||
|   clientCredentials: | ||||
|     enabled: true | ||||
|     clientId: "policy-gateway" | ||||
|     clientSecret: "change-me" | ||||
|     scopes: [ "policy:read", "policy:author", "policy:review", "policy:approve", "policy:operate", "policy:simulate", "policy:run", "policy:activate" ] | ||||
|     backchannelTimeoutSeconds: 30 | ||||
|   dpop: | ||||
|     enabled: false | ||||
|     keyPath: "../etc/policy-gateway-dpop.pem" | ||||
|     keyPassphrase: "" | ||||
|     algorithm: "ES256" | ||||
|     proofLifetime: "00:02:00" | ||||
|     clockSkew: "00:00:30" | ||||
|   | ||||
| @@ -1,27 +1,27 @@ | ||||
| -----BEGIN PRIVATE KEY----- | ||||
| MIIEpAIBAAKCAQEApK0BkUaZC26/J7el9fnYx1Y6Uwh0b3F08r5zixK9QmuaZ0+d | ||||
| Zn2m5yA/ty/G6uSVn/YU5YZd7zFTy9P7egfa/tVU5tB2Lk5/v/+6JCTG0uzQjZ1e | ||||
| tfx+/j/iKnD7Z3S2CQyq4F2VQQ2xxF+SaVQ9zbmqRaWhzVtzxz6pXPVH3YYBXFjC | ||||
| OXD2gG+437lPlm3CRWWPnk0hxK6SLlqVvFyP34PO8TdQF5VAcez5vFfwrkqXDBHC | ||||
| vQ156P6rWTeM1g9UUfPjCmaJC9k6uM4DUUDOVOA7xemlAf+QvOIbd1Yq+XNfYo6I | ||||
| WrE1bCnHgYG/Y2J17YrCX7bZ06WpDjXRHuEaiwIDAQABAoIBAQCm0sCcdwuDA1yS | ||||
| g52qZ2vBEtKgeAM9H9XD7VxVMdzJx/CbCcdE289kQTZrBp3fgpovvzgzjYQeojmJ | ||||
| 1oU3tEJX7AD1OCXikxBvl/EunzQ7Vm25Iw2zDX/a6li3jbDHNb/P5sNhoUqS2R7z | ||||
| gKqoq2oGOV3R43bHZ6N5UVoVDoRF0oZtl4Mw2aF/3JcBCQr9qsS1SoD/CPcaFc5e | ||||
| 2CiYtn0N+L61+Z1YblFXxUD6YJn/1XlonyDtNzW6ybMcyTj3y5DsKFnmQbF1R837 | ||||
| f6LS7IZzJ9Bod3lTY2QQoW8GrYc1Y4zM0P4ZfKw7u6nLLA/A4Ngpk+kuJoha+ffq | ||||
| /BQx3xU5AoGBANOltyQwXBuo5omywFbGi2+Z7UFip3yz1Vi6Yo4QzfdP/UVfhrlP | ||||
| IhiIC6cvI6bf7MwwN4vShBALTbctFRZpFj5Cil1Bh/n7dJE3KKdcBFDLndCszbb5 | ||||
| 21N4vR7BkfGav0PpVmeRlmy3FqnpYwm0KziqFwH2tsnegegcQFzN/Q0LAoGBAMok | ||||
| 2PKDwYhz523kn2AVVB8pB4X0ZPrZmtHh9bPlsJS7HwioX8Oo8CD5c+WQ4u4KnYV5 | ||||
| B2X2y8WTDdYH50SUSzjYCaec6Mce6CO5XrCK0pC6mvJMQBoBI35Snu461FahAE6U | ||||
| zNEp2bqMx8nKnuNRw1bI8gMlMrk0dBrJRvfUsycvAoGAcOVlC5+iB9YydUzFefvK | ||||
| xjBvXvG9Y60tdkN4Kd1/XiN7UjsfOCvy9EhRL1u5//JLi0O3bCtCO6fsziS0PFAO | ||||
| QX9WhCok0Ifn2GwzVDfteMoqmHhPmlKL0g7G70m2JdHMIiFAMJWpbD9gWKk0o9v0 | ||||
| Bk0zF0hjWG9ipN1fAv61TRUCgYEAk4fQVxbRyWYVvHHcH4scr1jYIE7so9+boQ3c | ||||
| O0YDyId+rLo0Orers/5OEI2gTgLz7HzFMr2SfLWaNqMy2Beo9/C8VM5ijx2zYNvM | ||||
| oN+xsZLFYoA7KM0jb5dLZ1UL84sHynwYLPy+EsB7mP+OpclAqY6cHx47CL4yxo2J | ||||
| cz0KkOUCgYA4hmgwRq3di82plhMnNs14UruI9SNpZbgZ7kFCCkQbGyRhPqbwIa1U | ||||
| AWhaI4SqdOskwj6B+GScXMiF49cDG4xW4Cr2/pr9F1ZcUEAWESihrINZhCg5kS2d | ||||
| FSKbJ2Xqs0GGx5xAxlzUaRF8NDH6cqfynlHC9HjDJSLXquGMEmXcnw== | ||||
| -----END PRIVATE KEY----- | ||||
| -----BEGIN PRIVATE KEY----- | ||||
| MIIEpAIBAAKCAQEApK0BkUaZC26/J7el9fnYx1Y6Uwh0b3F08r5zixK9QmuaZ0+d | ||||
| Zn2m5yA/ty/G6uSVn/YU5YZd7zFTy9P7egfa/tVU5tB2Lk5/v/+6JCTG0uzQjZ1e | ||||
| tfx+/j/iKnD7Z3S2CQyq4F2VQQ2xxF+SaVQ9zbmqRaWhzVtzxz6pXPVH3YYBXFjC | ||||
| OXD2gG+437lPlm3CRWWPnk0hxK6SLlqVvFyP34PO8TdQF5VAcez5vFfwrkqXDBHC | ||||
| vQ156P6rWTeM1g9UUfPjCmaJC9k6uM4DUUDOVOA7xemlAf+QvOIbd1Yq+XNfYo6I | ||||
| WrE1bCnHgYG/Y2J17YrCX7bZ06WpDjXRHuEaiwIDAQABAoIBAQCm0sCcdwuDA1yS | ||||
| g52qZ2vBEtKgeAM9H9XD7VxVMdzJx/CbCcdE289kQTZrBp3fgpovvzgzjYQeojmJ | ||||
| 1oU3tEJX7AD1OCXikxBvl/EunzQ7Vm25Iw2zDX/a6li3jbDHNb/P5sNhoUqS2R7z | ||||
| gKqoq2oGOV3R43bHZ6N5UVoVDoRF0oZtl4Mw2aF/3JcBCQr9qsS1SoD/CPcaFc5e | ||||
| 2CiYtn0N+L61+Z1YblFXxUD6YJn/1XlonyDtNzW6ybMcyTj3y5DsKFnmQbF1R837 | ||||
| f6LS7IZzJ9Bod3lTY2QQoW8GrYc1Y4zM0P4ZfKw7u6nLLA/A4Ngpk+kuJoha+ffq | ||||
| /BQx3xU5AoGBANOltyQwXBuo5omywFbGi2+Z7UFip3yz1Vi6Yo4QzfdP/UVfhrlP | ||||
| IhiIC6cvI6bf7MwwN4vShBALTbctFRZpFj5Cil1Bh/n7dJE3KKdcBFDLndCszbb5 | ||||
| 21N4vR7BkfGav0PpVmeRlmy3FqnpYwm0KziqFwH2tsnegegcQFzN/Q0LAoGBAMok | ||||
| 2PKDwYhz523kn2AVVB8pB4X0ZPrZmtHh9bPlsJS7HwioX8Oo8CD5c+WQ4u4KnYV5 | ||||
| B2X2y8WTDdYH50SUSzjYCaec6Mce6CO5XrCK0pC6mvJMQBoBI35Snu461FahAE6U | ||||
| zNEp2bqMx8nKnuNRw1bI8gMlMrk0dBrJRvfUsycvAoGAcOVlC5+iB9YydUzFefvK | ||||
| xjBvXvG9Y60tdkN4Kd1/XiN7UjsfOCvy9EhRL1u5//JLi0O3bCtCO6fsziS0PFAO | ||||
| QX9WhCok0Ifn2GwzVDfteMoqmHhPmlKL0g7G70m2JdHMIiFAMJWpbD9gWKk0o9v0 | ||||
| Bk0zF0hjWG9ipN1fAv61TRUCgYEAk4fQVxbRyWYVvHHcH4scr1jYIE7so9+boQ3c | ||||
| O0YDyId+rLo0Orers/5OEI2gTgLz7HzFMr2SfLWaNqMy2Beo9/C8VM5ijx2zYNvM | ||||
| oN+xsZLFYoA7KM0jb5dLZ1UL84sHynwYLPy+EsB7mP+OpclAqY6cHx47CL4yxo2J | ||||
| cz0KkOUCgYA4hmgwRq3di82plhMnNs14UruI9SNpZbgZ7kFCCkQbGyRhPqbwIa1U | ||||
| AWhaI4SqdOskwj6B+GScXMiF49cDG4xW4Cr2/pr9F1ZcUEAWESihrINZhCg5kS2d | ||||
| FSKbJ2Xqs0GGx5xAxlzUaRF8NDH6cqfynlHC9HjDJSLXquGMEmXcnw== | ||||
| -----END PRIVATE KEY----- | ||||
|   | ||||
| @@ -1,30 +1,30 @@ | ||||
| registryTokenService: | ||||
|   authority: | ||||
|     issuer: "https://authority.localhost" | ||||
|     requireHttpsMetadata: false | ||||
|     audiences: | ||||
|       - "registry" | ||||
|     requiredScopes: | ||||
|       - "registry.token.issue" | ||||
|   signing: | ||||
|     issuer: "https://registry.localhost/token" | ||||
|     keyPath: "etc/registry-signing-sample.pem" | ||||
|     keyPassword: "" | ||||
|     lifetime: "00:05:00" | ||||
|   registry: | ||||
|     realm: "https://registry.localhost/v2/token" | ||||
|     allowedServices: | ||||
|       - "registry.localhost" | ||||
|   defaultPlan: "community" | ||||
|   plans: | ||||
|     - name: "community" | ||||
|       repositories: | ||||
|         - pattern: "stella-ops/public/*" | ||||
|           actions: [ "pull" ] | ||||
|     - name: "enterprise" | ||||
|       repositories: | ||||
|         - pattern: "stella-ops/public/*" | ||||
|           actions: [ "pull" ] | ||||
|         - pattern: "stella-ops/enterprise/*" | ||||
|           actions: [ "pull" ] | ||||
|   revokedLicenses: [] | ||||
| registryTokenService: | ||||
|   authority: | ||||
|     issuer: "https://authority.localhost" | ||||
|     requireHttpsMetadata: false | ||||
|     audiences: | ||||
|       - "registry" | ||||
|     requiredScopes: | ||||
|       - "registry.token.issue" | ||||
|   signing: | ||||
|     issuer: "https://registry.localhost/token" | ||||
|     keyPath: "etc/registry-signing-sample.pem" | ||||
|     keyPassword: "" | ||||
|     lifetime: "00:05:00" | ||||
|   registry: | ||||
|     realm: "https://registry.localhost/v2/token" | ||||
|     allowedServices: | ||||
|       - "registry.localhost" | ||||
|   defaultPlan: "community" | ||||
|   plans: | ||||
|     - name: "community" | ||||
|       repositories: | ||||
|         - pattern: "stella-ops/public/*" | ||||
|           actions: [ "pull" ] | ||||
|     - name: "enterprise" | ||||
|       repositories: | ||||
|         - pattern: "stella-ops/public/*" | ||||
|           actions: [ "pull" ] | ||||
|         - pattern: "stella-ops/enterprise/*" | ||||
|           actions: [ "pull" ] | ||||
|   revokedLicenses: [] | ||||
|   | ||||
| @@ -1,2 +1,2 @@ | ||||
| # replace with a strong shared secret for the cartographer-service client | ||||
| cartographer-service-secret-change-me | ||||
| # replace with a strong shared secret for the cartographer-service client | ||||
| cartographer-service-secret-change-me | ||||
|   | ||||
| @@ -1,2 +1,2 @@ | ||||
| # replace with a strong shared secret for the concelier-ingest client | ||||
| concelier-ingest-secret-change-me | ||||
| # replace with a strong shared secret for the concelier-ingest client | ||||
| concelier-ingest-secret-change-me | ||||
|   | ||||
| @@ -1,2 +1,2 @@ | ||||
| # replace with a strong shared secret for the console-web client | ||||
| console-web-secret-change-me | ||||
| # replace with a strong shared secret for the console-web client | ||||
| console-web-secret-change-me | ||||
|   | ||||
| @@ -1,2 +1,2 @@ | ||||
| # replace with a strong shared secret for the excitor-ingest client | ||||
| excitor-ingest-secret-change-me | ||||
| # replace with a strong shared secret for the excitor-ingest client | ||||
| excitor-ingest-secret-change-me | ||||
|   | ||||
| @@ -1,2 +1,2 @@ | ||||
| # replace with a strong shared secret for the graph-api-cli client | ||||
| graph-api-cli-secret-change-me | ||||
| # replace with a strong shared secret for the graph-api-cli client | ||||
| graph-api-cli-secret-change-me | ||||
|   | ||||
| @@ -1,2 +1,2 @@ | ||||
| # replace with a strong shared secret for the graph-api client | ||||
| graph-api-secret-change-me | ||||
| # replace with a strong shared secret for the graph-api client | ||||
| graph-api-secret-change-me | ||||
|   | ||||
| @@ -1,2 +1,2 @@ | ||||
| # generated 2025-10-27T21:55:11Z via scripts/rotate-policy-cli-secret.sh | ||||
| policy-cli-iOHhrE+K1sx+iyWQOd9pqYh0LwbXRauO/zdv0AeFUvLKAtZsc1wTIB5qZ8YIfKEo | ||||
| # generated 2025-10-27T21:55:11Z via scripts/rotate-policy-cli-secret.sh | ||||
| policy-cli-iOHhrE+K1sx+iyWQOd9pqYh0LwbXRauO/zdv0AeFUvLKAtZsc1wTIB5qZ8YIfKEo | ||||
|   | ||||
| @@ -1,2 +1,2 @@ | ||||
| # replace with a strong shared secret for the policy-engine client | ||||
| policy-engine-secret-change-me | ||||
| # replace with a strong shared secret for the policy-engine client | ||||
| policy-engine-secret-change-me | ||||
|   | ||||
| @@ -1,28 +1,28 @@ | ||||
| # Signals service configuration template. | ||||
| # Copy to ../etc/signals.yaml (relative to the Signals content root) | ||||
| # and adjust values to fit your environment. | ||||
|  | ||||
| schemaVersion: 1 | ||||
|  | ||||
| Signals: | ||||
|   Authority: | ||||
|     Enabled: true | ||||
|     Issuer: "https://authority.stella-ops.local" | ||||
|     AllowAnonymousFallback: false | ||||
|     Audiences: | ||||
|       - "api://signals" | ||||
|     RequiredTenants: | ||||
|       - "tenant-default" | ||||
|     RequiredScopes: | ||||
|       - "signals:read" | ||||
|       - "signals:write" | ||||
|       - "signals:admin" | ||||
|     BypassNetworks: | ||||
|       - "127.0.0.1/32" | ||||
|       - "::1/128" | ||||
|   Mongo: | ||||
|     ConnectionString: "mongodb://localhost:27017/signals" | ||||
|     Database: "signals" | ||||
|     CallgraphsCollection: "callgraphs" | ||||
|   Storage: | ||||
|     RootPath: "../data/signals-artifacts" | ||||
| # Signals service configuration template. | ||||
| # Copy to ../etc/signals.yaml (relative to the Signals content root) | ||||
| # and adjust values to fit your environment. | ||||
|  | ||||
| schemaVersion: 1 | ||||
|  | ||||
| Signals: | ||||
|   Authority: | ||||
|     Enabled: true | ||||
|     Issuer: "https://authority.stella-ops.local" | ||||
|     AllowAnonymousFallback: false | ||||
|     Audiences: | ||||
|       - "api://signals" | ||||
|     RequiredTenants: | ||||
|       - "tenant-default" | ||||
|     RequiredScopes: | ||||
|       - "signals:read" | ||||
|       - "signals:write" | ||||
|       - "signals:admin" | ||||
|     BypassNetworks: | ||||
|       - "127.0.0.1/32" | ||||
|       - "::1/128" | ||||
|   Mongo: | ||||
|     ConnectionString: "mongodb://localhost:27017/signals" | ||||
|     Database: "signals" | ||||
|     CallgraphsCollection: "callgraphs" | ||||
|   Storage: | ||||
|     RootPath: "../data/signals-artifacts" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user