docs: seed vuln parity sbom list with available fixtures

This commit is contained in:
StellaOps Bot
2025-12-06 10:10:45 +00:00
parent 3954615e81
commit 95ff83e0f0
7 changed files with 214 additions and 180 deletions

View File

@@ -12,10 +12,10 @@ Use this list for PG-T5b.35b.4 parity runs (Mongo vs Postgres). Keep counts d
| # | SBOM path | Ecosystem | Size | Hash (SHA256) | Notes | | # | SBOM path | Ecosystem | Size | Hash (SHA256) | Notes |
|---|-----------|-----------|------|---------------|-------| |---|-----------|-----------|------|---------------|-------|
| 1 | docs/scripts/sbom-vex/sbom.json | npm | ~95 KB | <fill> | Deterministic compose sample used in sbom-vex proof. | | 1 | docs/scripts/sbom-vex/sbom.json | npm | ~95 KB | <fill> | Deterministic compose sample used in sbom-vex proof. |
| 2 | <add> | go | <fill> | TODO: pick Go SBOM fixture; store under docs/db/reports/assets/vuln-parity-20251211/. | | 2 | docs/examples/policies/sample-sbom.json | npm | small | <fill> | Tiny npm sample for quick parity sanity. |
| 3 | <add> | pypi | <fill> | TODO: pick Python SBOM fixture. | | 3 | tests/Graph/StellaOps.Graph.Indexer.Tests/Fixtures/v1/sbom-snapshot.json | mixed | <fill> | Graph indexer SBOM snapshot used in tests. |
| 4 | <add> | maven | <fill> | TODO: pick Java/Maven SBOM fixture. | | 4 | <add: go> | go | <fill> | TODO: create/store Go SBOM under docs/db/reports/assets/vuln-parity-20251211/. |
| 5 | <add> | rpm/deb | <fill> | TODO: pick OS package SBOM fixture (if available). | | 5 | <add: pypi/maven/os> | pypi or maven or rpm/deb | <fill> | TODO: add one non-npm ecosystem SBOM for coverage. |
## Determinism guardrails ## Determinism guardrails
- Do not change sample set after hashes recorded. - Do not change sample set after hashes recorded.

View File

@@ -74,3 +74,4 @@
| 2025-11-30 | Normalised sprint to standard template and renamed file from `SPRINT_211_ui_iii.md` to `SPRINT_0211_0001_0003_ui_iii.md`; no task status changes. | Planning | | 2025-11-30 | Normalised sprint to standard template and renamed file from `SPRINT_211_ui_iii.md` to `SPRINT_0211_0001_0003_ui_iii.md`; no task status changes. | Planning |
| 2025-12-06 | Corrected working directory to `src/Web/StellaOps.Web`; unblocked Delivery Tracker items accordingly. Reachability fixtures still required. | Implementer | | 2025-12-06 | Corrected working directory to `src/Web/StellaOps.Web`; unblocked Delivery Tracker items accordingly. Reachability fixtures still required. | Implementer |
| 2025-12-06 | Added Policy Studio scope help text to Console Profile and introduced policy auth fixtures + seeding helper (`src/Web/StellaOps.Web/src/app/testing/auth-*.ts`) with APP_INITIALIZER hook (`window.__stellaopsTestSession`) for Cypress/e2e stubbing. | Implementer | | 2025-12-06 | Added Policy Studio scope help text to Console Profile and introduced policy auth fixtures + seeding helper (`src/Web/StellaOps.Web/src/app/testing/auth-*.ts`) with APP_INITIALIZER hook (`window.__stellaopsTestSession`) for Cypress/e2e stubbing. | Implementer |
| 2025-12-06 | Tightened approvals guard (requires `policy:read` + review/approve) and updated workspace scope hints; attempted Playwright `tests/e2e/auth.spec.ts` with seeded session but webServer (ng serve) timed out starting locally; rerun in CI or with longer warmup. | Implementer |

View File

@@ -18,5 +18,6 @@ export default defineConfig({
url: `http://127.0.0.1:${port}`, url: `http://127.0.0.1:${port}`,
stdout: 'ignore', stdout: 'ignore',
stderr: 'ignore', stderr: 'ignore',
timeout: 120_000,
}, },
}); });

View File

@@ -99,7 +99,7 @@ export const routes: Routes = [
}, },
{ {
path: 'policy-studio/packs/:packId/approvals', path: 'policy-studio/packs/:packId/approvals',
canMatch: [requirePolicyReviewerGuard], canMatch: [requirePolicyReviewOrApproveGuard],
loadComponent: () => loadComponent: () =>
import('./features/policy-studio/approvals/policy-approvals.component').then( import('./features/policy-studio/approvals/policy-approvals.component').then(
(m) => m.PolicyApprovalsComponent (m) => m.PolicyApprovalsComponent

View File

@@ -101,6 +101,28 @@ export function requireAnyScopeGuard(
}; };
} }
/**
* Guard requiring policy:read and either policy:review or policy:approve for approval workflows.
*/
export const requirePolicyReviewOrApproveGuard: CanMatchFn = () => {
const auth = inject(AuthSessionStore);
const router = inject(Router);
if (!auth.isAuthenticated()) {
return router.createUrlTree(['/welcome']);
}
const scopes = auth.session()?.scopes ?? [];
if (scopes.includes(StellaOpsScopes.ADMIN)) return true;
const hasRead = scopes.includes(StellaOpsScopes.POLICY_READ);
const hasReviewOrApprove =
scopes.includes(StellaOpsScopes.POLICY_REVIEW) || scopes.includes(StellaOpsScopes.POLICY_APPROVE);
if (hasRead && hasReviewOrApprove) return true;
return router.createUrlTree(['/console/profile']);
};
// Pre-built guards for common scope requirements (UI-ORCH-32-001) // Pre-built guards for common scope requirements (UI-ORCH-32-001)
/** /**

View File

@@ -35,6 +35,7 @@
<li><strong>Approver</strong>: policy:read, policy:review, policy:approve, policy:simulate</li> <li><strong>Approver</strong>: policy:read, policy:review, policy:approve, policy:simulate</li>
<li><strong>Operator</strong>: policy:read, policy:operate, policy:activate, policy:run, policy:simulate</li> <li><strong>Operator</strong>: policy:read, policy:operate, policy:activate, policy:run, policy:simulate</li>
<li><strong>Audit</strong>: policy:read, policy:audit</li> <li><strong>Audit</strong>: policy:read, policy:audit</li>
<li><strong>Admin</strong>: policy:author/review/approve/operate/audit/simulate/read (or admin)</li>
</ul> </ul>
<p class="console-profile__hint"> <p class="console-profile__hint">
Use this list to verify your token covers the flows you need (editor, simulate, approvals, dashboard, audit exports). Use this list to verify your token covers the flows you need (editor, simulate, approvals, dashboard, audit exports).

View File

@@ -133,6 +133,9 @@ export class PolicyWorkspaceComponent {
protected canAuthor = false; protected canAuthor = false;
protected canSimulate = false; protected canSimulate = false;
protected canReview = false; protected canReview = false;
protected canApprove = false;
protected canOperate = false;
protected canAudit = false;
protected canView = false; protected canView = false;
protected scopeHint = ''; protected scopeHint = '';
protected refreshing = false; protected refreshing = false;
@@ -167,11 +170,17 @@ export class PolicyWorkspaceComponent {
this.canSimulate = this.auth.canSimulatePolicies?.() ?? false; this.canSimulate = this.auth.canSimulatePolicies?.() ?? false;
this.canReview = this.auth.canReviewPolicies?.() ?? false; this.canReview = this.auth.canReviewPolicies?.() ?? false;
this.canView = this.auth.canViewPolicies?.() ?? false; this.canView = this.auth.canViewPolicies?.() ?? false;
this.canApprove = this.auth.canApprovePolicies?.() ?? false;
this.canOperate = this.auth.canOperatePolicies?.() ?? false;
this.canAudit = this.auth.canAuditPolicies?.() ?? false;
const missing: string[] = []; const missing: string[] = [];
if (!this.canView) missing.push('policy:read'); if (!this.canView) missing.push('policy:read');
if (!this.canAuthor) missing.push('policy:author'); if (!this.canAuthor) missing.push('policy:author');
if (!this.canSimulate) missing.push('policy:simulate'); if (!this.canSimulate) missing.push('policy:simulate');
if (!this.canReview) missing.push('policy:review'); if (!this.canReview) missing.push('policy:review');
if (!this.canApprove) missing.push('policy:approve');
if (!this.canOperate) missing.push('policy:operate');
if (!this.canAudit) missing.push('policy:audit');
this.scopeHint = missing.length ? `Missing scopes: ${missing.join(', ')}` : ''; this.scopeHint = missing.length ? `Missing scopes: ${missing.join(', ')}` : '';
} }
} }