diff --git a/src/Web/StellaOps.Web/e2e/audit-consolidation.e2e.spec.ts b/src/Web/StellaOps.Web/e2e/audit-consolidation.e2e.spec.ts index 32021fd47..3118e386a 100644 --- a/src/Web/StellaOps.Web/e2e/audit-consolidation.e2e.spec.ts +++ b/src/Web/StellaOps.Web/e2e/audit-consolidation.e2e.spec.ts @@ -264,25 +264,28 @@ test.describe('Console Admin extended audit tab', () => { }); // --------------------------------------------------------------------------- -// 6. Integration Hub — Config Audit tab +// 6. Integration Hub — unified audit cross-link // --------------------------------------------------------------------------- -test.describe('Integration Hub Config Audit tab', () => { - test('Integration Hub has Config Audit tab', async ({ authenticatedPage: page }) => { +test.describe('Integration Hub unified audit cross-link', () => { + test('Integration overview links into unified audit with explicit integration scope', async ({ authenticatedPage: page }) => { const errors = collectErrors(page); await go(page, '/integrations'); await snap(page, '06-integration-hub-default'); - // Click Config Audit tab - const auditTab = page.locator('stella-page-tabs button, stella-page-tabs [role="tab"]').filter({ hasText: /config audit/i }); - if (await auditTab.isVisible({ timeout: 5000 }).catch(() => false)) { - await auditTab.click(); + const detailLink = page.locator('a[href*=\"/setup/integrations/\"]').first(); + if (await detailLink.isVisible({ timeout: 5000 }).catch(() => false)) { + await detailLink.click(); await page.waitForTimeout(1500); - await snap(page, '06-integration-hub-config-audit'); + await snap(page, '06-integration-detail-overview'); - // Should render integrations audit component - const auditComponent = page.locator('app-audit-integrations, .integrations-audit'); - const visible = await auditComponent.isVisible({ timeout: 5000 }).catch(() => false); - expect(visible, 'AuditIntegrationsComponent should be visible').toBe(true); + const tabsText = (await page.locator('stella-page-tabs').first().innerText()).toLowerCase(); + expect(tabsText).not.toContain('config audit'); + + const crossLink = page.locator('a[href*=\"/evidence/audit-log\"]').filter({ hasText: /open integration audit trail/i }).first(); + await expect(crossLink).toBeVisible({ timeout: 5000 }); + await expect(crossLink).toHaveAttribute('href', /module=integrations/); + await expect(crossLink).toHaveAttribute('href', /resourceType=integration/); + await expect(crossLink).toHaveAttribute('href', /resourceId=/); } const criticalErrors = noCriticalErrors(errors); diff --git a/src/Web/StellaOps.Web/e2e/fixtures/live-auth.fixture.ts b/src/Web/StellaOps.Web/e2e/fixtures/live-auth.fixture.ts index 92b78a77a..4dd77d23f 100644 --- a/src/Web/StellaOps.Web/e2e/fixtures/live-auth.fixture.ts +++ b/src/Web/StellaOps.Web/e2e/fixtures/live-auth.fixture.ts @@ -9,7 +9,16 @@ import { test as base, expect, Page, APIRequestContext } from '@playwright/test' const BASE_URL = process.env['PLAYWRIGHT_BASE_URL'] || 'https://stella-ops.local'; const ADMIN_USER = process.env['STELLAOPS_ADMIN_USER'] || 'admin'; -const ADMIN_PASS = process.env['STELLAOPS_ADMIN_PASS'] || 'Admin@Stella2026!'; +const ADMIN_PASS = requireEnv('STELLAOPS_ADMIN_PASS'); + +function requireEnv(name: string): string { + const value = process.env[name]; + if (!value) { + throw new Error(`${name} must be set for live-auth Playwright runs.`); + } + + return value; +} export const test = base.extend<{ liveAuthPage: Page; diff --git a/src/Web/StellaOps.Web/e2e/integrations.e2e.spec.ts b/src/Web/StellaOps.Web/e2e/integrations.e2e.spec.ts index 6ef02c2f1..be074036b 100644 --- a/src/Web/StellaOps.Web/e2e/integrations.e2e.spec.ts +++ b/src/Web/StellaOps.Web/e2e/integrations.e2e.spec.ts @@ -22,6 +22,17 @@ import { test, expect } from './fixtures/live-auth.fixture'; const SCREENSHOT_DIR = 'e2e/screenshots/integrations'; const BASE = process.env['PLAYWRIGHT_BASE_URL'] || 'https://stella-ops.local'; +const ADMIN_USER = process.env['STELLAOPS_ADMIN_USER'] || 'admin'; +const ADMIN_PASS = requiredAdminPassword(); + +function requiredAdminPassword(): string { + const value = process.env['STELLAOPS_ADMIN_PASS']; + if (!value) { + throw new Error('STELLAOPS_ADMIN_PASS must be set for live integration cleanup.'); + } + + return value; +} // --------------------------------------------------------------------------- // Helpers @@ -258,8 +269,8 @@ test.describe('Integration Services — Connector Lifecycle', () => { } const usernameField = page.getByRole('textbox', { name: /username/i }); if (await usernameField.isVisible({ timeout: 5_000 }).catch(() => false)) { - await usernameField.fill('admin'); - await page.getByRole('textbox', { name: /password/i }).fill('Admin@Stella2026!'); + await usernameField.fill(ADMIN_USER); + await page.getByRole('textbox', { name: /password/i }).fill(ADMIN_PASS); await page.getByRole('button', { name: /sign in/i }).click(); await page.waitForURL(`${BASE}/**`, { timeout: 15_000 }); } diff --git a/src/Web/StellaOps.Web/output/playwright/live-frontdoor-auth-failure.png b/src/Web/StellaOps.Web/output/playwright/live-frontdoor-auth-failure.png new file mode 100644 index 000000000..2db582924 Binary files /dev/null and b/src/Web/StellaOps.Web/output/playwright/live-frontdoor-auth-failure.png differ diff --git a/src/Web/StellaOps.Web/output/playwright/live-frontdoor-auth-report.json b/src/Web/StellaOps.Web/output/playwright/live-frontdoor-auth-report.json index 52d860b41..42f6134f7 100644 --- a/src/Web/StellaOps.Web/output/playwright/live-frontdoor-auth-report.json +++ b/src/Web/StellaOps.Web/output/playwright/live-frontdoor-auth-report.json @@ -1,55 +1,58 @@ { - "authenticatedAtUtc": "2026-04-15T08:23:58.746Z", + "authenticatedAtUtc": "2026-04-19T10:08:12.266Z", + "authenticated": true, + "error": null, "baseUrl": "https://stella-ops.local", - "finalUrl": "https://stella-ops.local/?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", - "title": "Dashboard - StellaOps", + "finalUrl": "https://stella-ops.local/auth/callback?code=eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiJZV0pPRVlCSzU3UEpSQTFTSFhFWkM3NEFRQktRWFdEQjZaWlVPV0dVIiwidHlwIjoib2lfYXVjK2p3dCIsImN0eSI6IkpXVCJ9.IDXJmN_y55KXyQfQck2Fk2g49Mwgi6qrbu4GFQBt-Rsq0Ja-td8huvXXbB4ZH0DTPpAjFdDLqGxCVVEurC9WuxTJ2BqdQjXgHBVz7HEat_l3wITTSC5IjQiprxE43W0wJ-18u82uc_b3eA7k_TBOkaETA6K85h-r0aWHPk21eLUFJ6RsMbkY_uGi8T098-9UNvKiJ-r2Em3KXzs5uhBgUWjv_eUlxXqy1I3kL4VwKb-Owv6D1I_4N_v02wLlJjLmj40I4rc6AC01-QnnWGDAXQqXbz8GvarIUxGRlVvd_siGDaZHqKaMScV_6k3mzK8AyQMfmH1GzKDJtHpHmbBItw.wl-qD35iFGQCPthi9hlXGQ.OKdcas-sptgtseIuePWdXeHzO4Itv_Gm2FVPPKh96Isuo_GBkXHs4vgmnANz7sq-_o1dMJLUREOWR964NV7AQaq1vvIK3xkcyvkQCVrXHte1rcTXdIYXz6J89SyUN0lJ1NnSWusjYFXnFLt3T1OznwFBo_ry_hgmnieHKYn_deAFXOAj_cisYG9DgTZ9DADecU6a9_TeDEKFgRc-WTXKUlvjsn4XSMnq_lD26dyGP-iGVYfXd21bdzZIo2DzOSzYtchA_CWF42cz5VchrBH19yPJbKJBoh0BDIw5uVRrfk6yw0EZndglVOAoxQdiKinIxOhYeryhc2qoYeT4tdEKB-zJcQ7XUHKYsT4crsjzgKwNr7m0pKUpSMRS-T2ttqHMl7tDMKsVYSsngpVl3bII-RSqBK7cSSzjwCyd0TbBuCSM2aRKhbD5yGzEhhuIA85TOgIlnLJmG_XmGX9P3b0KjPZEQoYZU30aYvf4lB84KbyMX9WHBi0kGDVOleuQK7ZqMOXqRDo8mt9aVKkDJaV7nwNJYTw2omgNGepFz5_0euprC7PZZBnRrw7L494AngJUR3Ku1qKtxvNwXv8Inm9G-q7B9CtFMYU8UA4YBLmVtnIeFrJgxzIeDxEKRHC8U6EKs1ZipxCalGudjAMR4drJoBjYAGazKU85rlR0SLBomH-YtY7MLHXWaiDSOeOCZpf1CDCMI-vJADNGovBRXczd_xIjKEquzlsuK0FfE1IXQBxwYLKEw6CaTqgP4LsdSWWYyf9g5vUpfgvFlnMPEOoWmmzR-Ul-5LoS_OY52_f32adYRlODwL84_kM00JPxh4xzLIUup3BLP01SRo5-1o18QtCihs1IfzFvWKoPq76YiQ00s51FwqRzd_SDc9Fh8Zd7zgjCtZ0wEKYaU2wRmPeI7UNroT_p2I3L8aKE_fcdlEIjRvT-bb893S7YDYAVaihyS1NTi3O-C7TdWx85UIMjeuBzhPw2iKfSuuSa5GJzPUMtZBoq0U_Eo2SnLLzva1n2N-jtlpv5N5gnPJV17CDHHeTBbSQkjBg8OIbTQcGsSEp02feFQ6DQ5uFM1mj7yEIaejMbeXdIDksmwPDitUoO4BwNOGOFVyboU2XpXPxA-FzdM3APC4UOGUHhaA4u2e-S0zKV_gKT9G1mEbD9axO8IvfMdV_Sk8xUejqas3vHk0yo8-mNP-MzlYdnEnQZDzTezEcIhOkUUH-p94DAAZq-L32Y3XxeFxkZsbvQn01_o6jJHnCLQYuND19d9Uak4oOK_y3KVFiGwN6xdqJMIbHF6ULnMkFFbqsOAmg0Fb9ktg1Eu0o4gywTKNQg-ynYTZ2SLDcfZouheP1y2vZODTe9dEh6HYdAptThS0ayQWLUW7hcFR9vQtmZi0jS2CZf8QBjPQ69J6D-aj8X9FNCJvvhMq2mo8zOQEQc1Yj7MF2FwQSs7vZjHEFcyo6tO81N-c36ufgKK2F1zIVzDyOYPFLQK9tcH2yY8Wmndvo9pv3YTHlgUhideDBObfX7wW7-Oe7A_-JvwakHdWY21qBmY68R-AfYhPyUbMQ6k6X_prQhdobFl51rxDUbNeMEOiwl4sistfrDvoLzotUxSY1fZEI2tJJPhkFvsR5WXwQMmKw65_sbuln_uSzuSErWtGPYfyzsma_cRlycTi0OqkRvBn-1gyynbXwaYGHyx-lcrn3ePARewzIKv5eJhgZLgxscttf1GHpw9x4yeRgNOqpC1pr9zOaA0x0bgl-VWRJ_LR8ZyjnkjX9NDjhWHmwBvxacbrGSWlVC7wAu4SHWjZYTuKPJrGaq1XFEWwdbxFdWCx1T4wayzUF12HokprZMXg20JhKa6OJi3rIHblQlAgoq_m3vyfcs2EGtOCw6s6t1VzviUue7EKsR4H_eTo3oqlv1VuSrqycpzNeUJcF8N43utSNVEhIQnt6Ec20S6jaMVfPdRaCOmI113Y75laM6Dz41Mc0xp_rEp9B-B1x9pmy5k7C93e44M-hAgRQcVNEc81rjSC6Tgpt_vXqobFvIu68tMeJ0JxgAfixc2KbIYbvxolV9yy1Y9WIVX6Fmn2jNrRQfwu9N4M-2U4cMH6K83Ltsgq8qgGffnGUq5aOu9WUpSiHRiu_jiE1N63RB8Ys60YK969J6o_f2eBzpP8oJfldMHfJ7nXzVL_Diql_Gt_yZdTzks83tMnNRS0XCrUTRRC8zec7960xywgC6nvn3lMS5J9aInnUSNp7v92m3C5Esw20UTnv8dsuEjnHqEa3uVGaZg-b0xp5d8oklmOgJqGsVlZ8XcFxsgxhVT574-_G2qPGr3azF1DDUXSqQI5g8BNBSHJOuiYq89TwS-uRlyti-mhB6Qommo1zKlfOKHNdEk9VWGoYH4LouhWRXBNE3Ez282oAl-c-gAWtIdI1hwCl0bnG3HsMpSApexF6PuX3QtwTq33glR7Ovw_i8BTtYRUWC4evgidDJeBv7opgo75xNwXg9bDZypbjZxLsT-kjUNu7Epw8BAEf-I1YmBJZQboqVwFtJLwS3bb5V0NjP5IXwf5lUp6zkxe7Wq50jnLOQwa_0p3K2PKpAm-_nl5begrS368DdEMhQ2CvuOh4D7Qkmsn59OsdkQNla2_N16JKc7iPN7xrvQcDnAmNsVRVIgmyyE5oGQfrHUAwVbnNQgb6IQyACWG8cCt_HFsdxp-tOOZYXW_X8sKi0uYhbkrJtePlc3vu4gU3MYilo0CwM8RUzRBXn_QLc1QKhSbFHkIx7C3GjjtWM_CeTyA9dGhjnrt6wR_SKMuk8MB8XFy39IMhOR75S8PAZpL5zSX10Xohou09SHR_mrqHWy5sP_VHx2RRQWnWuCQBPiXwl0eQeQh0X7PGIeNqzgkPRjVc-OwSS2-9gc6YEtvmZYtKI8yh2zNWHgSoBJk9zf-9393s7wcDY-7gZU61W4yFYxI_oZplBXbD6b24IOcsRjiHlYaWEvfASMEGH7svXtiq5ia2e7Gu4v66sWOntAGaFlo8Lq-5uM9L3CJ0kMnZ9llGbQ0bIRT5DsVHmgA7VuOrCt7IkFc1l4U8ezQUYgIxtWpT7QpTzDQRKQzOKYYeEKOwoZv7jWKE1ytExnHy6KRyXeklol4IkXXJlJoPMvAmH67qiRqTf0tcxzsZoK2Ss6iKBHIQshmm7q6bC2F98cedeaE0-5WapKsZWq-J7RGgZ-b7eaaJyohHY14-iXPeYaNEp5RRwanKb9vD-PXP5r6MvTjW89EDVDyZI2f-SM_Nc0lQg8um56TB1d1hbXYOu5jLv__GjDatsaUM8OcC0YgvixzuWjO-JkZg84dvS9EoeygPw33FgfxuFJrhrfIVbaLmK3Pf_0zFE2-Gf7_OK-7auRFO_PbQ2jkeViusQWwPUKfV4Ew0gpaRvXHLkdl5mkCnlxvg9ENHYi5p18hiP8K0c2HcJSDOIkxbMHHz43RzJtX3-LAAFxIcFFLr8GaRnzqfnOZvs07afm9ymUo4v4Tf8TwulTq1xhswtWVHABmIdrc0kOm2IWyPlYFEvNDS1jHJrZCtbs0wH13PeMDAHHrRNj13ThERQNi4icfJyJ9lKoZeATLLtDZ-PFK1GbGDHI7HcCfI6-2r6MZJ7ZVrjGtAJa0hVhymgK70GCJtnctV5OMzKGB0LSNlNnpt0v4TDpbzz9FLo1rjIPv-UNrH5Gmsbl7tKoW8fOniFJHkSakUpyfdiDzAqDy8NxPRggGPsz5Yuqc4YdL-EWqshUf_WhCmnK-D1QDfCLsNpxK8HQBbFMVSqH5nIo9Ey2D-eSU9Udgz2WWtSra-YPsy-GOZiYaJlt0__npOYfp86AkbuBKbhNnksoHes-S_mlLTxlW7Svc64QOAvSgunqlvaFjVrognkxHAsOuarNtay-o6SJkWcjkqJt3qK90tj3lSf_8_3EYVfCVCJCi-KVI0Cnln9AOmoLGw_lzKe3_AfUJzk569b8EsLzM2d6JFpdgn95fNWb7nVxRf_NIVonjlgyVPuuJcJzgDGlM-GruNfLwoVj81bBZrG4X5OMYEdhb7nAItOj3eio6dAWqPnAfxSlzlVoXCnl6fIDl5H64c_nrOGkE1FFCf-2_GSEby2fPawSNqFrJgkj2DIv9-I9ZP7nW6ONq9kCWEo1UchpXhl5KVLfoMEce18xJi8jgLC6lLewcru47oUX2UcY-urUrNVawY8s6JEiqnCnJ6PkU_HAo1HDL8Mo19tKXEaIakQXS5WKbCsyhviD08evyrv3ZFOUdFbHOuJ8WlKKWX20eg-bYUDzFghEDRsuJoP8d-9NTZ6vKWEniHgLkIrAh74bJKzpJQB5xBmeRPE6KjeUUbD9XcflDWa8Xvqb8q2dX_zr05oiB75lEwzemzITzWigRLhbbJSb23OrPgTEHTjoqEXb62suM6-tWZFyFKOtQgjLZpj5Fngrh4Axfx6hpznPedZ3o4bDY0IhlYoHLCaEk20GXMkre6gRfp9llmVJGtrPCoC_5P9ofKZrx253OSIF_DIWz5mmK3X4XUvb_kGL24eegRKL9JdYr_hmKCuMUB6YzBiK79X9Nx28O9I7j9zvJHwbYbEOoPqXyXfF4tC_psL.GJk49TeQyEpyH4Q2BwlvJ4ZzD5mLAOHjN7xjD7dcvdk&state=3625aa20-9cb3-48c6-83dd-6dde75733845&iss=https:%2F%2Fauthority.stella-ops.local%2F", + "title": "Callback - StellaOps", + "bodyText": "Stella Ops\ndefault\nf945f00811f44f008058268a264ed015\n\nCompleting sign-in…\n\nSecurely verifying your credentials", "cookies": [], "storage": { "localStorageEntries": [ + [ + "stellaops.auth.session.info", + "{\"subject\":\"f945f00811f44f008058268a264ed015\",\"expiresAtEpochMs\":1776595090118,\"issuedAtEpochMs\":1776593289124,\"dpopKeyThumbprint\":\"knhtz_ieCuFgS2A6bYdUWWhbWQNMcly969VVWFBQoAA\",\"tenantId\":\"default\"}" + ], [ "stellaops.auth.session.full", - "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6Ikg4TkdITjJESUNPUlE5QUpGTUlFRzlXWVdTVVlSUUw0LVJXR0E5QlEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjI0MzIzNiwiaWF0IjoxNzc2MjQxNDM2LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiZmZlZGY3MWQtYWY1MC00NWQ5LTlhMzQtMmNiYTE4ZTVmMWQyIiwic3ViIjoiMzRlNjllNDdkMzE2NDdiODkzMDc0NDk0NGYyZmZmNzAiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYyNDE0MzUsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.BAPTbUxstvf4uSVv4bcKBCxCWam0MHZ8KxaaqIygmYnTng7xnoN6x2ub6s0EjAbQRY7M67gP_ESywOOMkklH_iIXEixCEQLueAIyvbFmo21ssmDY2SclXtInuXsIosZfKpqraYcvn7nO9DdqDa44hZ6OVbFJTkrGjJCjazhApR5VD5hiAK53_swYhVPuPXCXNU38aExVPPazAu4C4QuDBJuy5Rp4tne92Uzo60tad-ojOMGT-7ILkDWqzp_SPRSuvbQuyzQEjBGGljSeoUqUnRg7Q4gj1u6XwyKMhTvbA6n6KtcgsPGLK6_AzspFqxOuMicjgcvY93pcnnm62b8EAg\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIxRVlZNFdJNFJfWE9HSDZVRFRPTFBUV0JQSE1QUlZaWURBS0FaRjcwIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.OjzFbXMVmR9utsZHxNNBb7lKfzW1tuD2V7uE6_WIo7viJTqvK5Pc70225amfOn_ppciNbsQtdWqtULoybzWVR-dOKJ7xN8vDcmhVJCvlHOTdVVZIw9fkdRDpsUXkabUFWC8hjpAd1ol-x5Y56EpB4LHmEBYRRV2g1g9lBMcnK8ARBoLwgrsK1xsR_Vueg9bvbcnbQdDoi_tgV2jORtPQ3WUyzNECt8WY0cMnU7AP43EcU5agg4r5SLJ4qYCoGRrEasAaH3kIEQaZLRqIlCNF1x-77vvMdYVDpqkLLgQF2bg2EM32_DIyccxSzdKFqyzTWieOfz8nnR_cgdpWITOjug.-ZgbI6MR19kz4G8ueQfOgg.w3F0J2tK722wQD6NcNcIrOXtj4ZkmYNy-mf-aK08l_TBUpHwqTByrAz3XfmD7SXtO4DqC0H-BdjxeBGbnnMxTjNG5BwtGN0wNZbYPd7yBm8eJy7ay6VhwpRBHDUm0UBUL-Onk0mcgD3vi_POkeBv54zFFJBqcijN3ia70Eim19HgxLkFop5LYebbWkX4juRRz6fI5KLglBrQnF6FTPaz3gq65PUbyAW1qQpdv1fw3n6S0YjkQzV_96sBsx7iLexfT16AwRRfmPiUOTpPljcfDtSHXKK4n0y4TVHdDb5FoOmf8WuloMAVPUzVjVuwJqZk169I8Yx-eyP62yWJYKNNaPE0-YQ9b7XXub2U3StSSMagPTNM8RG3Yxe2pnQDIoW5v81Q6Qdek7xktmooL8WNnFMBd4udNOsMCeGk98QTuXHXVVKq4zNuVuBgFoCWAWMBGGNVZXXtiELgwH3lE9IoUlbdMsGUBAQ-vcj_QFlzAGGonAp2YUMX3pY-bnqfzhp0cWMjBJxUK8-iRWmmw-1cMKtNSEqlg21bEDUQBFDJTMJENC31kaaqCfny8wNu90Oi9faTzx_bjAtFiH83XB1c-J0eTa5BBdWbd7Mu7U-hryne0RWK1wCkf97vo9aB0xclHxnQA2v-gtp-rtpb8QkvYS91D9YvpHyuPEhkQK3liyKRXvQND-6tMwDrcFoj9_7XyukAjw1WEKnjQG7u9TnH81ejB0nHVDOhwWGMxMIA8EO0_ql9MfGvIN3Cy_O82MlIthSn5-V7aakV_dyZYkvEcKZ0UBrSxCwQSKAS9cqmew0ud3fzzp8cAqwNMDHvkECw_YN8LBJN7FfpPXxnOsKveySv-IISsOxae9A5i9BPYh0OJ0jxKxI2XmnOqspdGZu-5D5JVZDBrqlDM4b84SECSuLnDkejV7_N1Cwt0YogU7lckvaFCvmuQ0xmhdWBOvlXtyEgGjr7HpviX_64utAR5ItsXu2QK0tVq_mmXiL9nNqsPqO13Qy2GJhtg_5GLXVV7GFztNVzaxu1Yu8tSEuhMWJ2aKx5xkaY5jr4pzW9gkgx-TQBQrkwSvKm2NVGxX74StxQwo-3vM0V8uUhlGxOBH2WNC8SbsPXdwsb3yad2c-0itweIm9znnGg7ePxl3NQFLVaBQiW1wiqJta5iSb970fTJ560wsNt7ooBDw2Ux5lGeEGNJC7F4X6KjuvZsONSJRkyguiduDVDytbN_PAvIGPPFsCNzdY3K9rw-fd3vABygfYWxhUacWTbHq-jFfYHijBJPQ4J7uzh-gr2O5dYODCg8uo3h1Ka-p9tXX1D_uLsfjHc62Sp3LaFZ34tFWzq3cZKKllmDWgpECgySFXLKHKRAP1GCahWkgyf3PW1j4liK3Xxaqq4W1-UokwOLyacWD5Gw54JgY2o43BpQZuK3pRjSaoyB2PErrNrzsdw9f_gHSa8-z7xvoQSjegyIjAB9UN0-h7pb-cozsYsvhsFm_4E7d6aCtmn80QQl5w7_8MyuuVngij65B8jRXxlUog-lQGSm-q3ZyMrWK8puR7KpokgfUl1qwOM1N-5WxDGHQHFeD2Hm-9mSmQfv3coF1rHmh65fk3kzubaMZoPEXFTtEwQtmhRVAS5F4JFniT_hX3xuthylEtW12b20EkLWfnSt_bH3tL0Ig48I4Z7P8w_v7kQNS8qjiAMaOstE48fOfc36y5Pk89uyDC_Zji2exOugPJ8E_YeaEhzhFeMHxwEq2JGWAzXwhma1wZ8BkNNWyMOLNhd5S0--OqnhArs09RCEpzpoWSNDa3aInE4QjNcEdQsMFyyCNa_1Pk9qXM8DLDPueh_BS7EhVhWNOoYLmBSZKFZHksB6LQngbWr9CS4RHedCw1zi5KriZKDSkLGwFrpBeXs2d2UGPqO-Wyz7ea6wtZ4MLWXpXJASlr0OYEEvR48DphIs--UPvTRf8pyg0O5ZBk45AwEl7twN85IYwlX01swbVe9V8Eur1hJBCKPUYn9WBs3SVP5wYURnO8ukOt2UIQCPzXG1qGTmGk88Df-TlsunUmVsHnPChzGxyew1FCwV4R1YDuc0BBd3XH1mlv2656lQ01Fht9l-gt06a2RwIJTZL4y1Vh3DYcvKWNBw-LLGjo7rOL8u8bADx_-cscu-Rs_n9PKFzuQfu5VZsRpMiIIJ8qnEqaHX5Mcy70gbRYH91mDXEdpAYykr4olwB1sG-yP5H10A7nKExx24YoToZbxgEyZuV7HZ5xrcreSIQ-uFH2S6I7nkYhm_3QshyHP1kn4UrUemrcVpAa97x8IUT6LSjJEQ6i6vH0akluHMFjPcf7o1UndrVUGOlux-kd3i7LD5Qp4x1fB3NTaOoPvsZGuBdTxLh5nxO55FU2afldTaTYVhgm9V3yrJ16p2wWj8cR8XbmGk-0ociK0FLjVgSVBK9oPX5OhMkYQYI0JQgdLfM_1PPvxBkJPU9Bv7OuVc3oFm9Vkf3CDgl2kNh9HN7Pi4eUDydqgwcO_WQqpLkbHV-V3IAMyxJRyvLBvNDkOLmyDzbg5CCUwVZuKugASUoud8qEqn-jupPGXxqzpUi7cBrgxM3CfULa3idzknLszw8K9utCjsazoyewSiWUN7V7L6b18Rp4gLMZ9M9NBRMHNa2Uf9htGb-HK8L0xNKlab6EYY0iNMRV00RLbHlAbgKntj8pfD0Ox5y5AgqFNxJ1m2dWMoo_fsXiYNvAYN9DBLhewds1SsOQ4X7Q-7FCJKIceeiIOUbbpoCqJnxg_ZF-eukpA5QicuZv60qvbp-QBFt2x22TBIFtphJB-uNudY2_inRyt3VYZJGr-juUgxaMDTJ8WDiLyVqO_Dnd-vvU_Z0DF4xWiuVi5LVuYPO3etlT9ibfqJKne6Wf8bO2zQ7-A3KMgB1VY_fZmG0-13YHunTqGhIhLpkAqJJgcb8i3CQK0csGADE-_pLl7BwfbAq1WKAVtmU5QT-uAfvn1mjAv4Q6htO4wSzCW41Ij_i_VifLKZ8S_cZADmWxxBtWvwxgBfxIeoxY26zk0E63j6ZhmqVqM8bt-IRlm5Jfc1D3wWhZ9Tp-BGT4qZSmP2nVzyvyc8bE0wF2ANIF-Ks0Dh8KW9XRd_bma0BupJAHooAh5oFHhvr8qThWYGRdY9E4Jk6XkTElVe9X8FpimkkEGyDMltmCScbYDR3QGsHURbkBHYcQ1u6nb87PravJrBCd9Lw62P0ImdSOzHKmgM2xDkh7M0taCG_7kM5sJDplhJD14Oiz3CxlOTwci4TRr9kICpkdp0kr10xvQi_x_xTuxUynlKHl4OvyQ7RksdB39w1be4NRo4wYfbzAjGdK_KUwdQSJwyAK4wh6SKFnc8TfaVyqp4fy_drb_TAxH7nyHkeS0m9FRZOjaYmXNko0dX8_djS7hVdxcdjLpX50r9duN2kJ35cMbszsRyhnXr4JuIdVziEvSRs23jKgDwKXFld7uvV6QPTa6eEctpJXTlUSNZMhJxEfT-pO6Dbmu5oIYzus5ogQRqlohHyVOOndFhhR2T4MgxVczLc7Nu_M955mnNdGn6Dwz_kClAMOxCkLB6HuGF5pjoTb4UJcL93LP0Hw7FiKoaBectNrQPEyk-c2ycY2rFuoyuvNYdBBo-FPnTpP2O89mjkhL8-9RcFmKxN7UHniK2WDdu0uR0y3icm6zH8ABAZsduy8mhyDqx2YNQjhy5tfmoxkAIVUsL9YAt1o45wenfI1dW_p4bnxxEGVl3mUbRBswN8wc3CuwsxcWRNRAVZWC2WADLqgMUkInXDyLcijfoJ1LNxCo_6og8UIMKb7ix6uao4VSMnYO9mNE5SCq5jalPkjwhXfJiJL9RdRhB5rd5t3Dw7OrJwvcSY1EwVMT7z-l-6Zv-q7Q73NlzHU6Spx1AwrKx3fAIEX_LRULI-15Zsp4QcFc4qtAkzw07CTGzcBPQD88zHq3VcL1zVzToFO4f-exWsg0QdXwdipI3EtV3M-DyKXvHYNBKcpeIG8h95_EfcXfWXxAszyGfCDdGY_bxOzi9seh0A5LP0b5ZJa3lwcFWYtMEGL0G3yNUse-Aoqr0mZtdslMiHk7LO__E7fb3we82QwA316JSf7VRhnqSZIo-EuvKF0F2J2wmWea99bbD6wZPvJ6DD5YPfnTZ6ApXiJhnt8M5FCbjqefT3mwMhiMEVVFwKqqR8nH73NJtfz_lnfrWKRJ14_MohDCXFCluFWmSWyJ19e_co7of-_H7BrYBog9jmuJCFw4a2dUcE1tffnDI-sbsP8YdwOZ-RX6cEmllnCyhRFiC8UXACRmo6Jnszuz4UgXnz_DzmNF_mxzLg2TJzF8GG-63C25xE-lA3iYABoMQiPus79ki8gqxx_JW1h2yph1sghDHyWnBYKM-Ev9iDLXBfIhW2J8DYEDCdSqQbw190-sQIN2D0QQI-CP1O3MXze-ZZ8sZD4BU9rjnMJzmP7P_HG7pH-UqSbb2fOG80tZksYicLK0FVx0hIzAiB57ZIKqTOIQ08LhgF98RRXEZ7M5oz4P4dg4vaWHiM7lD92lXraJQ1KZcgBCGDyCHQWPrBzmGi9TJKrgkQvJwYPaxT7AazSkWsMDE9tWHX0LN_3BS48-ntxWmzBP8ocYudCZUo7hS0V3AJ0-KS_BYLY5KM-MepF2BYnN_iPn_tfuuCyKho_lw6QeiyrnWK1Yz8IWSoPueJ-ME02YLX3P9KZmN3dOD8zIkbju03v4PxJSL5yLtgHwmjRkYQ.cjOvEX-7aFRdot2RsGMsT7sykvFcQPb73BRcWRYb7us\",\"scope\":\"openid profile email offline_access ui.read ui.admin ui.preferences.read ui.preferences.write authority:tenants.read authority:tenants.write authority:users.read authority:users.write authority:roles.read authority:roles.write authority:clients.read authority:clients.write authority:tokens.read authority:tokens.revoke authority:branding.read authority:branding.write authority.audit.read graph:read sbom:read scanner:read policy:read policy:simulate policy:author policy:review policy:approve policy:run policy:activate policy:audit policy:edit policy:operate policy:publish airgap:seal airgap:status:read orch:read orch:operate orch:quota analytics.read advisory:read advisory-ai:view advisory-ai:operate vex:read vexhub:read exceptions:read exceptions:approve aoc:verify findings:read release:read release:write release:publish scheduler:read scheduler:operate notify.viewer notify.operator notify.admin notify.escalate evidence:read export.viewer export.operator export.admin vuln:view vuln:investigate vuln:operate vuln:audit platform.context.read platform.context.write doctor:run doctor:admin ops.health integration:read integration:write integration:operate packs.read packs.write packs.run packs.approve registry.admin timeline:read timeline:write trust:read trust:write trust:admin signer:read signer:sign signer:rotate signer:admin\",\"expiresAtEpochMs\":1776243236072},\"identity\":{\"subject\":\"34e69e47d31647b8930744944f2fff70\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6Ikg4TkdITjJESUNPUlE5QUpGTUlFRzlXWVdTVVlSUUw0LVJXR0E5QlEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjI0NDczNiwiaWF0IjoxNzc2MjQxNDM2LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiMzRlNjllNDdkMzE2NDdiODkzMDc0NDk0NGYyZmZmNzAiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiIwMWIxY2NhYi1iYmM4LTRjZjQtOWZlOC0zOTMxYWQ3YTJkOWMiLCJhdF9oYXNoIjoiVVRmc3NvaWJkUTFEM29UTFphMnlnZyJ9.ZWgl9L3OfXRvrrRsuHaaMXM-GVyYWjnF0PKI2Z4Q3xaCHJVY4dnvs54bBhjqYYWiaq9naM2KdLOTc3_KcAyiTPkqNbQPmHbxvfOAgYMt6Y1Og3lhcuuK2Lx9ZAIKBTlHK-QwaGANhOJ55oc9-JXsYKZHcQFMn-N61USb1fFz87ETzYfwBncYIDSCiYH3imu4uKrjvtgJ3xq6RTkKoccWuEs3cIyfc2xVC5sIk333tParluN983CyRe6qjMnFq336DzfNB8oGW3qVNuXfZaVyzABdrHyWXrwkTg_6wbPwTFHX1TEFOcszKEWV3SP4Pb8Sp8HuqxoLdMxdrLyQX_E-CQ\"},\"dpopKeyThumbprint\":\"DMsuRsgxj4LVVAKUpzryYlk0KRfhmt92uKKrhB36dmM\",\"issuedAtEpochMs\":1776241436074,\"tenantId\":\"demo-prod\",\"scopes\":[\"advisory-ai:operate\",\"advisory-ai:view\",\"advisory:read\",\"airgap:seal\",\"airgap:status:read\",\"analytics.read\",\"aoc:verify\",\"authority.audit.read\",\"authority:branding.read\",\"authority:branding.write\",\"authority:clients.read\",\"authority:clients.write\",\"authority:roles.read\",\"authority:roles.write\",\"authority:tenants.read\",\"authority:tenants.write\",\"authority:tokens.read\",\"authority:tokens.revoke\",\"authority:users.read\",\"authority:users.write\",\"doctor:admin\",\"doctor:run\",\"email\",\"evidence:read\",\"exceptions:approve\",\"exceptions:read\",\"export.admin\",\"export.operator\",\"export.viewer\",\"findings:read\",\"graph:read\",\"integration:operate\",\"integration:read\",\"integration:write\",\"notify.admin\",\"notify.escalate\",\"notify.operator\",\"notify.viewer\",\"offline_access\",\"openid\",\"ops.health\",\"orch:operate\",\"orch:quota\",\"orch:read\",\"packs.approve\",\"packs.read\",\"packs.run\",\"packs.write\",\"platform.context.read\",\"platform.context.write\",\"policy:activate\",\"policy:approve\",\"policy:audit\",\"policy:author\",\"policy:edit\",\"policy:operate\",\"policy:publish\",\"policy:read\",\"policy:review\",\"policy:run\",\"policy:simulate\",\"profile\",\"registry.admin\",\"release:publish\",\"release:read\",\"release:write\",\"sbom:read\",\"scanner:read\",\"scheduler:operate\",\"scheduler:read\",\"signer:admin\",\"signer:read\",\"signer:rotate\",\"signer:sign\",\"timeline:read\",\"timeline:write\",\"trust:admin\",\"trust:read\",\"trust:write\",\"ui.admin\",\"ui.preferences.read\",\"ui.preferences.write\",\"ui.read\",\"vex:read\",\"vexhub:read\",\"vuln:audit\",\"vuln:investigate\",\"vuln:operate\",\"vuln:view\"],\"audiences\":[],\"authenticationTimeEpochMs\":1776241435000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" - ], - [ - "stellaops.helper.preferences", - "{\"dismissed\":false,\"tooltipsMuted\":false,\"mutedPages\":[],\"mutedTipIds\":[],\"seenPages\":[],\"tipIndex\":{},\"dismissedBanners\":[],\"seenHelpPages\":[],\"pageHelpOpen\":{},\"pageHelpDismissedGlobal\":false,\"pageHelpDismissedPages\":[]}" - ], - [ - "stellaops.content-width", - "centered" - ], - [ - "stellaops.assistant.state", - "{\"seenRoutes\":[],\"completedTours\":[],\"tipPositions\":{},\"dismissed\":false}" + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IjdLUks4OUw1UTNESkVQR09IV1NPSDNMVDktTVdNWVVJRS1aSU1VX1EiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjU5NTA4OCwiaWF0IjoxNzc2NTkzMjg4LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiZTk1MGE0NGUtZmMyZC00YTJkLWFkNDAtM2YwMmVjYjRiNjQ2Iiwic3ViIjoiZjk0NWYwMDgxMWY0NGYwMDgwNTgyNjhhMjY0ZWQwMTUiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZWZhdWx0IiwiYXV0aF90aW1lIjoxNzc2NTkzMjcyLCJvaV9wcnN0Ijoic3RlbGxhLW9wcy11aSIsImNsaWVudF9pZCI6InN0ZWxsYS1vcHMtdWkifQ.UQHuPO8JY_GQUzB-pPcos1eZJqPcbl3BaygXNnGUdlL1tz4C5P9PkHEPGH1LyNrJuPIzPSLI8Jx9vbXOF5VlTo2qfb2-NvalYkmuz8RTxDoevWpOfaFtoZLqWuOMy198pC_HKpxw6LMe9OxwRtN7n6OHB1jqGZWCmlJvEkWLvrrCqhIpnvFLcuC6l1Q54S2DFTEw1ahMYKMMmwtAFqAnfY5IPIZAdVJ9t7Ax8-Jski3vteSf1z-YIrdpEzEUv-5SXqNsgeNhHcE7-cdujOb4CMJsK4cLvBBZd2miZBkbRHs9ass19hXFPxhv4PgjuyrD9FNy2xzvPevbc2ykuvf6hw\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiJZV0pPRVlCSzU3UEpSQTFTSFhFWkM3NEFRQktRWFdEQjZaWlVPV0dVIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.J7ia8dvkcB0Bs0Z7yx_-BwUPECUq397tiuUOpc-tGIdWSNs9CvHHRj_yPGlU06Fmpr1bkelR5wpD7jy_8f-xc1OZmOWVCk4qrJSoCB_VhA8M5rf28xbLswNhj2OhP5_Lj9b9obaqzWwpLNAPl4wDaJBgOPW5hYNoVsoDcAZH3DB4jeALVLu6J7B3q5BLNAw-QRIgaEF7z8uutLrvs8-Dv0PgI-XcEGKQonmlml079_5jKEkKdiEAVCionn-2ksFkvLcDhK8DkDuPTvieHmnnz6Oi55XlBjlOr6-w_zV_3VA7L0zHozTKDFMUaVPqpU2rZU1ggA-hGMkb1zoBddoYiw.yFzbv7Vg3lA28Fu7wpT0Vg.TgCK7wAm6_JSQgq5ZL2YGNfNRNbAfsjx2_8WqtNwjRFiXg-dJt3OrOIljaz8bGivi3QLBOuyCrG4z_UXBITf5gcWd--BlW_XG8tvRfyXRFp9JsJqWxFl4_CwNZZNBCQpZVAy8g_oNSDhQhOyCW_rKK12GuRRv7swXkJKqkwTBLmAcHP6u-ewPheFufWSqWtf_-l1JdvaM69GoSOeiU9fx9ZWZabq2bKu8v1CM5D9_xVqq-RzKNP_DefvAn-nsElnNmVaTlKNmnu1R3K93mKorvL6aOpE1QtEzAkPyzEu7vrV3bJcoVv8YKHnJKuO7zT6gXJe5WHtcJDgHGjdjQd_Ca-fQ2nDaDk7PXmbOL8gLOUZRf1duuN5DAvlKqCehMEil_luv9w9aUX7dgHgZq3cJu6hM68Gr_TuPdCpPlQauTEyO81dFMD4ACNTwDWrnHpL36ChOl4znQ_gXjUS07T3ls8cG4FFu3v84FDUSJBPDjUIFoNZ5aR2LHrR8K5JhROb4fwu4wQf_EQPeNBTnMfmm_TeeSJUGkx7U2vD2IAPm_r3UgAmt9lS2ry4t8Xk8Alzg32ijARHAC8Tgu301p6RH0MgmbllwGbNBH1AwTyabytngpfda0Nu37NzKPZHha4AdotX4GjVKBXqA0TRzmgQR9Y_crlmQbjdGNselt7DD_OUpVgIX6uU4pnf2YoiyhAE6LwmFvLyAElgEf7d2rYe1q_Nb_rYerSWf4E73I2nwlsHs7Rcq9C3_z2y5mb35bMLj8chOiRAlW7rY5g2G6ybwAEz0RiUgxgULk6VHbfZgAoBHnCG0yB6hjbYjIrpA3bg3LJhHPcZGER8kU6p9bAZx5zR7AQ9xoO0wrwTQiyuHFRgHct2YYQqvjewzw8oDRsjx_jiNKg38vyXgccZgCVgSjQF6-xQYu-6-GU0CgNzgjPdl9UuQW4cN_ewwb5S9MZWcMPNXGKsyuG_hDemD1-n3B2bXyx2RaXi8c_QRWVj8BMY0cmTBiAvm-dPacbj4Gqk1SU7sqR-yyAH9L9MkSx0ok9p7VvvwjbPmXSfY8Savvls0ziWJOld21vPKDVbKD8PVWDWOKTsSSGbWXIyJTSVWfULDk3i2UjysL5JOhtcZrKokj3ERHvZKHMNMqckHz_MM-nRfS6aItguhBz8anl73WRcE9vTDdmAUUjP-XFyb_BG7ZZ545CTR9UUB3LQAPbbMQkFpmSUtdGvb4lL2AOWfQNMY9dpCkC7SlS4XDYDYcKe5rzjbNhG3cHfgvPxFkyygj5-JZ3hjIPpqytBl2omD3IQ05uRTWcvPLPc22FVb2E7UTDzOFASWTyKbfT9lBFNDemOQrw5EtNUYuc5RPKxUx0Uj_NFWiXjuxTmjl1db3ka-wWwQIEuUlQ4XACo7tWgJQNHN9VbAIobImoOMRB4K4JNN9ekJ4R2Mn_Zcz8B85Zjxn1ajwtmUyTszCPpXKorRG3eMR1kPFJO5eoYWFs1TLlXIAQYtv9niv-NitzVoOmAYkcanVB0hfN9q-g8hCRV4YvgjJzFQtcKcKSkaTFMYuB2wNT0yfag_nSpZM15aClopt1aFcEb2BaLZ3KgHxiAnU-3M3FjIgp4PK4XbT-shJJO3EsYDRtFpYLQZSaWuIopd3PheQNOIQCX_-__giM7xB7zOTv5NUkO5kzDWxRdMtbxua7jf6Xh_R715K0feg7WXu_t0GI-0E1E5AhzIqfSHOn4LDqi4muG4TMLtAt7qHbHgLOHrGvWUTWm65rKWo3rSCH_bb8mM_qRq5wRrxNjgWP-389Z7w2uTwvuqHlyrk9_5F16zcTBFYsrdsyNpsdNetv0B9_ukaBR8pZhHmqcwjKN8mwBdcxk7aSieUhSzLQ5WyZoaV0i0JKHeGX9uhjQEzZ2PjzHmP0UUEqc_lxpxLIm67p7wkT-Qf988PwqzUOqNLbXy-7KHkB9HeJMxWHRpNTo85hsCw3580E7oC5je4rDmzPSb8IPgLylZzwT3zA9We4K2kJWxv14hPLPbbRn3R0bhmx3FrAjrfiC14Rc7mrMdFatWI5kWk9H-QHhlIdOhlfmGMDmZdgxecsQqYUNAp-S2KH97KX5G8UqSVPaT8VJWz6KIAegjlo4-mJDOmyhAYELlsX1eNceO8RsY1mreb0JSXxuE1L_E0KrqfXKlqaIxZptlwtbFYKUo0A9lhImct9W0CyzRUNoPSk9efy1RUIYMwITMyzhfSYWOBPqEH3O3fbS_TOG7K2BrLC5_0HpATFMp3kWIZIPREvGfwNSHUrMVhNdukewix3zxdfGRsE2bG1C2xBIWnRHsdKcZa_DoLf6EHomz9OlGnYsrqtBV3vB6MzDGgb4Es6A9HTxynhtEEaTeuO_BAEmGuPBYGmNfaE8cx37LmRL33nK9v9zQvlaqSmeJeE53G_tTNsv98aDR9dtWlJgsIU5U9lTwepYSz6unzUf3-e0yDO0sE1nmyGIqvknAO6bxhPfmTE9xDQTZyU0YVjAL6XfOeQidaconqfh9DEFfqKxfbskymACi2WSE_4YjJYlEw1gfn-w3t5yggj8mQ7jeH_rWY6mxb7kaNFvMoVjUaqaJxtoGZEsgQVd0K3eFoAMC4tfzbX9oGwKNr-27e_5DbugDqlunZLBchhlM5o5gsBQqv3-JNk69erVOKWctI79yTIIUoKWtxqlLMMVSo2dcIb2TthKyyk0XKnKs7nLxT5lSsOJ3K8qeA8bF8_ikEi9YLnp88EoQOp-O7VEQ6JOgDy9Kv_NlV_jYrBpjJZsNe2kGzaTpw0Nf7ncfLvc90CsdcWylJTN_s9do2vJtpP1Kwa-nc8hdLqTyrt5G_oImjy62qcvDWE-G6bLjLGXkIcmAE-Lic_AXk7Fy86u6fxKs3pSDQK03zKOmsethMJ3meOz6mmjH4e2kcsK8V1UVJtffbW0h1dhv9aT96ODpL50udZUkyyk_iJVnEqhFJ6-ayHBGUVjBHrK5T1FbG7P0PoI7uTHkpYnRkqr9LOUBBdtBE6W0evjgWLLlVVjvK-QyDaVmLzY5YsU_nHwHOUB0n-iqPbsgf6Pnu0-e7qf081jXSr7LRnt8lB2BY1CwGWdnDVdapM4vjVxa7Kg4thKbm_ktcwtPJAUiXn_JkV7OF6M4YX2-N32JN6-3EKW5e9wnig-xjo4XjNEKFQ5Ln40iK2KjKfkLBbyRmhE1v3d7YON-uIAff0yI2ip4X_nW-PTOydWFcsgRcGOUR4VArzfZHKl17J8fSwJM4EGfE56do70PaAUcy1yHZfklIlZ-dvUQJEqkY6zqMdeZGtI0JAaIBi5vnNiXFWhXf2jZ8t9MpHq37w96CguhnV4pDoT9W3MsOqiJxTC256FDj-zWbfx7FDDPJ-VmtDnJjY2SluPLR4YRwLVcNLlhbjzAv2qaw1TrmNh_TBNPs0qLypdRpKMYyrjaLtLRoEjkFfR8nmt_5DR8X6GgcU2O55lFEn8Uzz9LqeLeaWaGuHQJqFQboY8tdVHvV8R9ijTRzG-P3vSWX6K8F9Y7FAbm25MJwWEJf6VWaHLDKY-wxs6OPdSBOdK--zWfNeRHg4gCt_L1Rk0j81PslGKe71cthqy8E4yIJErXWczUtcKx0pT4gynkT0viifpvisyTeXpW9_0gTKG6b71FFConwwomUwpZpoY0nO7xc4PT07Ph6f4FpgjkOtIWCukBf-LXwhaio_bAYQL34GPFusr92AypxO_9ZHkcY-SYt3H02PkjdDazert9k_XCSkahdiWnmYtC-2yDY8we-H1OHD4XyQbb2ReMRo9hMSrWv3StwSlHDJO0FT_TSHzWJnRk2rJPpoxaCnY53zfCkzsiViVrE5m4Ys3pBQBpIUQFcUNqmEt3d6-vuissmQAsEb9oBpmWaqC3cGV-6qz-uFD47VUYii7_3HDxtkc23FbcItpLKn0ECL2bf8AVbmou7qwI4KBU3R_tSI-DQtlms1tSpA4Bs1X6Z30a4wsl1nn4DEHC2Ln4lJ6CKixZaElcHlueDL-bUo13X5onWnP3xuhMdBBBpQcR_UidK3WPNfOKdsrrSmit6zyLJHX4CXA07LC__BzW8ZFX2IHQiXsxbMD7CN8tyiayPi-iDj25No-bCvWLV0SRQf_rB2Gt0tvObDHr4gNW6hCI1KRaBlKVfh5y5XfrNu8eFJW0KAi1Cxl4IKBQooS7DgbVRdt17EuOeR9AHrd7h5TqtV2UL5GzH-_n_02CzU47pZ3CACHQfbXVWpW11-YQo112p0P1gXb_kgpsSfxktzg9RofQ6Y1uAX84AkFyUw3Y1T50MBZR27XNq7WA1ovhaheEqvgfDL-kmLfqBoQl6OZ5b6L433rC0HKRQV5JtKxoulOEckKGIL7NAss6-ogKq582M3rkMjFuppcpKKZR_ix8lhAXLzniJMHqpxnyhuUK5mMAG_CzOSTlL-YSL2VWjMs3gmzOjqTAcs-JiRMzD_eMEsCoLSZ_otth8Aw4_Cj6tISca62_OFNPGvtcGCuGeNDsIxmx2doWXJ65yuAR2BekymdBe1tTiUWE9FrUCXZt20DxZB4eVvOAYainfUwPR-GKhHQXSHqVLcg-O45BaUHJ1Se_eXEJy2fSNaKOjfD_M2XVSUR_xo0LC9nUGzVBmY.3_UfBuwJIBsAgxZEYYD1TG0u_JsZbiZDqPwdoP-3_8E\",\"scope\":\"openid profile email offline_access ui.read ui.admin ui.preferences.read ui.preferences.write authority:tenants.read authority:tenants.write authority:users.read authority:users.write authority:roles.read authority:roles.write authority:clients.read authority:clients.write authority:tokens.read authority:tokens.revoke authority:branding.read authority:branding.write authority.audit.read graph:read sbom:read scanner:read policy:read policy:simulate policy:author policy:review policy:approve policy:run policy:activate policy:audit policy:edit policy:operate policy:publish airgap:seal airgap:status:read orch:read orch:operate orch:quota analytics.read advisory:read advisory-ai:view advisory-ai:operate vex:read vexhub:read exceptions:read exceptions:approve aoc:verify findings:read release:read release:write release:publish scheduler:read scheduler:operate notify.viewer notify.operator notify.admin notify.escalate evidence:read export.viewer export.operator export.admin vuln:view vuln:investigate vuln:operate vuln:audit platform.context.read platform.context.write doctor:run doctor:admin ops.health integration:read integration:write integration:operate packs.read packs.write packs.run packs.approve registry.admin timeline:read timeline:write trust:read trust:write trust:admin signer:read signer:sign signer:rotate signer:admin\",\"expiresAtEpochMs\":1776595090118},\"identity\":{\"subject\":\"f945f00811f44f008058268a264ed015\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IjdLUks4OUw1UTNESkVQR09IV1NPSDNMVDktTVdNWVVJRS1aSU1VX1EiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjU5NjU4OCwiaWF0IjoxNzc2NTkzMjg4LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiZjk0NWYwMDgxMWY0NGYwMDgwNTgyNjhhMjY0ZWQwMTUiLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiIyNGNiYWZhNS03ZDNhLTQ0ZDMtODgzNy00NTIyYTQyOTk0NzUiLCJhdF9oYXNoIjoiSzZqRXhqdDFmMFZZVlVtbWF6T09JQSJ9.EcbkBfurdz6gfBT_5_TP6vz2aNARKP5BiEhDoBKkY4esokvWoCxPQfT6NozP4sEde-lofT4W1w1GNavRDO7QN51C6YFM25DplqcX_QWGC_UhinUd2w_WkNtzYRDjVdpTMI7gnEch77IZ0pKAKaSTNwSTLIeGG-q-SZr1M_HiIjbG0x2-kzwolGrXxVuA5XXQbWNoFW0W9PdFKpz6SNicVi_D3WM2rvRkSF_-gZ4byilC7uIZ-o45HllQceM1EAlUObQMG01b-XDMaFCAY243GY0NzRZ2pgvPD6X6SuZPtAAzBPWGm71EU2w_DyVlZt7hTGyKl-SGt_hwSrXMQ1oDdA\"},\"dpopKeyThumbprint\":\"knhtz_ieCuFgS2A6bYdUWWhbWQNMcly969VVWFBQoAA\",\"issuedAtEpochMs\":1776593289124,\"tenantId\":\"default\",\"scopes\":[\"advisory-ai:operate\",\"advisory-ai:view\",\"advisory:read\",\"airgap:seal\",\"airgap:status:read\",\"analytics.read\",\"aoc:verify\",\"authority.audit.read\",\"authority:branding.read\",\"authority:branding.write\",\"authority:clients.read\",\"authority:clients.write\",\"authority:roles.read\",\"authority:roles.write\",\"authority:tenants.read\",\"authority:tenants.write\",\"authority:tokens.read\",\"authority:tokens.revoke\",\"authority:users.read\",\"authority:users.write\",\"doctor:admin\",\"doctor:run\",\"email\",\"evidence:read\",\"exceptions:approve\",\"exceptions:read\",\"export.admin\",\"export.operator\",\"export.viewer\",\"findings:read\",\"graph:read\",\"integration:operate\",\"integration:read\",\"integration:write\",\"notify.admin\",\"notify.escalate\",\"notify.operator\",\"notify.viewer\",\"offline_access\",\"openid\",\"ops.health\",\"orch:operate\",\"orch:quota\",\"orch:read\",\"packs.approve\",\"packs.read\",\"packs.run\",\"packs.write\",\"platform.context.read\",\"platform.context.write\",\"policy:activate\",\"policy:approve\",\"policy:audit\",\"policy:author\",\"policy:edit\",\"policy:operate\",\"policy:publish\",\"policy:read\",\"policy:review\",\"policy:run\",\"policy:simulate\",\"profile\",\"registry.admin\",\"release:publish\",\"release:read\",\"release:write\",\"sbom:read\",\"scanner:read\",\"scheduler:operate\",\"scheduler:read\",\"signer:admin\",\"signer:read\",\"signer:rotate\",\"signer:sign\",\"timeline:read\",\"timeline:write\",\"trust:admin\",\"trust:read\",\"trust:write\",\"ui.admin\",\"ui.preferences.read\",\"ui.preferences.write\",\"ui.read\",\"vex:read\",\"vexhub:read\",\"vuln:audit\",\"vuln:investigate\",\"vuln:operate\",\"vuln:view\"],\"audiences\":[],\"authenticationTimeEpochMs\":1776593272000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" ], [ "stellaops.theme", "system" - ], - [ - "stellaops.auth.session.info", - "{\"subject\":\"34e69e47d31647b8930744944f2fff70\",\"expiresAtEpochMs\":1776243236072,\"issuedAtEpochMs\":1776241436074,\"dpopKeyThumbprint\":\"DMsuRsgxj4LVVAKUpzryYlk0KRfhmt92uKKrhB36dmM\",\"tenantId\":\"demo-prod\"}" - ], - [ - "stellaops.sidebar.preferences", - "{\"sidebarCollapsed\":false,\"collapsedGroups\":[\"evidence\",\"setup-admin\"],\"collapsedSections\":[]}" ] ], "sessionStorageEntries": [ [ "stellaops.auth.session.full", - "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6Ikg4TkdITjJESUNPUlE5QUpGTUlFRzlXWVdTVVlSUUw0LVJXR0E5QlEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjI0MzIzNiwiaWF0IjoxNzc2MjQxNDM2LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiZmZlZGY3MWQtYWY1MC00NWQ5LTlhMzQtMmNiYTE4ZTVmMWQyIiwic3ViIjoiMzRlNjllNDdkMzE2NDdiODkzMDc0NDk0NGYyZmZmNzAiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYyNDE0MzUsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.BAPTbUxstvf4uSVv4bcKBCxCWam0MHZ8KxaaqIygmYnTng7xnoN6x2ub6s0EjAbQRY7M67gP_ESywOOMkklH_iIXEixCEQLueAIyvbFmo21ssmDY2SclXtInuXsIosZfKpqraYcvn7nO9DdqDa44hZ6OVbFJTkrGjJCjazhApR5VD5hiAK53_swYhVPuPXCXNU38aExVPPazAu4C4QuDBJuy5Rp4tne92Uzo60tad-ojOMGT-7ILkDWqzp_SPRSuvbQuyzQEjBGGljSeoUqUnRg7Q4gj1u6XwyKMhTvbA6n6KtcgsPGLK6_AzspFqxOuMicjgcvY93pcnnm62b8EAg\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIxRVlZNFdJNFJfWE9HSDZVRFRPTFBUV0JQSE1QUlZaWURBS0FaRjcwIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.OjzFbXMVmR9utsZHxNNBb7lKfzW1tuD2V7uE6_WIo7viJTqvK5Pc70225amfOn_ppciNbsQtdWqtULoybzWVR-dOKJ7xN8vDcmhVJCvlHOTdVVZIw9fkdRDpsUXkabUFWC8hjpAd1ol-x5Y56EpB4LHmEBYRRV2g1g9lBMcnK8ARBoLwgrsK1xsR_Vueg9bvbcnbQdDoi_tgV2jORtPQ3WUyzNECt8WY0cMnU7AP43EcU5agg4r5SLJ4qYCoGRrEasAaH3kIEQaZLRqIlCNF1x-77vvMdYVDpqkLLgQF2bg2EM32_DIyccxSzdKFqyzTWieOfz8nnR_cgdpWITOjug.-ZgbI6MR19kz4G8ueQfOgg.w3F0J2tK722wQD6NcNcIrOXtj4ZkmYNy-mf-aK08l_TBUpHwqTByrAz3XfmD7SXtO4DqC0H-BdjxeBGbnnMxTjNG5BwtGN0wNZbYPd7yBm8eJy7ay6VhwpRBHDUm0UBUL-Onk0mcgD3vi_POkeBv54zFFJBqcijN3ia70Eim19HgxLkFop5LYebbWkX4juRRz6fI5KLglBrQnF6FTPaz3gq65PUbyAW1qQpdv1fw3n6S0YjkQzV_96sBsx7iLexfT16AwRRfmPiUOTpPljcfDtSHXKK4n0y4TVHdDb5FoOmf8WuloMAVPUzVjVuwJqZk169I8Yx-eyP62yWJYKNNaPE0-YQ9b7XXub2U3StSSMagPTNM8RG3Yxe2pnQDIoW5v81Q6Qdek7xktmooL8WNnFMBd4udNOsMCeGk98QTuXHXVVKq4zNuVuBgFoCWAWMBGGNVZXXtiELgwH3lE9IoUlbdMsGUBAQ-vcj_QFlzAGGonAp2YUMX3pY-bnqfzhp0cWMjBJxUK8-iRWmmw-1cMKtNSEqlg21bEDUQBFDJTMJENC31kaaqCfny8wNu90Oi9faTzx_bjAtFiH83XB1c-J0eTa5BBdWbd7Mu7U-hryne0RWK1wCkf97vo9aB0xclHxnQA2v-gtp-rtpb8QkvYS91D9YvpHyuPEhkQK3liyKRXvQND-6tMwDrcFoj9_7XyukAjw1WEKnjQG7u9TnH81ejB0nHVDOhwWGMxMIA8EO0_ql9MfGvIN3Cy_O82MlIthSn5-V7aakV_dyZYkvEcKZ0UBrSxCwQSKAS9cqmew0ud3fzzp8cAqwNMDHvkECw_YN8LBJN7FfpPXxnOsKveySv-IISsOxae9A5i9BPYh0OJ0jxKxI2XmnOqspdGZu-5D5JVZDBrqlDM4b84SECSuLnDkejV7_N1Cwt0YogU7lckvaFCvmuQ0xmhdWBOvlXtyEgGjr7HpviX_64utAR5ItsXu2QK0tVq_mmXiL9nNqsPqO13Qy2GJhtg_5GLXVV7GFztNVzaxu1Yu8tSEuhMWJ2aKx5xkaY5jr4pzW9gkgx-TQBQrkwSvKm2NVGxX74StxQwo-3vM0V8uUhlGxOBH2WNC8SbsPXdwsb3yad2c-0itweIm9znnGg7ePxl3NQFLVaBQiW1wiqJta5iSb970fTJ560wsNt7ooBDw2Ux5lGeEGNJC7F4X6KjuvZsONSJRkyguiduDVDytbN_PAvIGPPFsCNzdY3K9rw-fd3vABygfYWxhUacWTbHq-jFfYHijBJPQ4J7uzh-gr2O5dYODCg8uo3h1Ka-p9tXX1D_uLsfjHc62Sp3LaFZ34tFWzq3cZKKllmDWgpECgySFXLKHKRAP1GCahWkgyf3PW1j4liK3Xxaqq4W1-UokwOLyacWD5Gw54JgY2o43BpQZuK3pRjSaoyB2PErrNrzsdw9f_gHSa8-z7xvoQSjegyIjAB9UN0-h7pb-cozsYsvhsFm_4E7d6aCtmn80QQl5w7_8MyuuVngij65B8jRXxlUog-lQGSm-q3ZyMrWK8puR7KpokgfUl1qwOM1N-5WxDGHQHFeD2Hm-9mSmQfv3coF1rHmh65fk3kzubaMZoPEXFTtEwQtmhRVAS5F4JFniT_hX3xuthylEtW12b20EkLWfnSt_bH3tL0Ig48I4Z7P8w_v7kQNS8qjiAMaOstE48fOfc36y5Pk89uyDC_Zji2exOugPJ8E_YeaEhzhFeMHxwEq2JGWAzXwhma1wZ8BkNNWyMOLNhd5S0--OqnhArs09RCEpzpoWSNDa3aInE4QjNcEdQsMFyyCNa_1Pk9qXM8DLDPueh_BS7EhVhWNOoYLmBSZKFZHksB6LQngbWr9CS4RHedCw1zi5KriZKDSkLGwFrpBeXs2d2UGPqO-Wyz7ea6wtZ4MLWXpXJASlr0OYEEvR48DphIs--UPvTRf8pyg0O5ZBk45AwEl7twN85IYwlX01swbVe9V8Eur1hJBCKPUYn9WBs3SVP5wYURnO8ukOt2UIQCPzXG1qGTmGk88Df-TlsunUmVsHnPChzGxyew1FCwV4R1YDuc0BBd3XH1mlv2656lQ01Fht9l-gt06a2RwIJTZL4y1Vh3DYcvKWNBw-LLGjo7rOL8u8bADx_-cscu-Rs_n9PKFzuQfu5VZsRpMiIIJ8qnEqaHX5Mcy70gbRYH91mDXEdpAYykr4olwB1sG-yP5H10A7nKExx24YoToZbxgEyZuV7HZ5xrcreSIQ-uFH2S6I7nkYhm_3QshyHP1kn4UrUemrcVpAa97x8IUT6LSjJEQ6i6vH0akluHMFjPcf7o1UndrVUGOlux-kd3i7LD5Qp4x1fB3NTaOoPvsZGuBdTxLh5nxO55FU2afldTaTYVhgm9V3yrJ16p2wWj8cR8XbmGk-0ociK0FLjVgSVBK9oPX5OhMkYQYI0JQgdLfM_1PPvxBkJPU9Bv7OuVc3oFm9Vkf3CDgl2kNh9HN7Pi4eUDydqgwcO_WQqpLkbHV-V3IAMyxJRyvLBvNDkOLmyDzbg5CCUwVZuKugASUoud8qEqn-jupPGXxqzpUi7cBrgxM3CfULa3idzknLszw8K9utCjsazoyewSiWUN7V7L6b18Rp4gLMZ9M9NBRMHNa2Uf9htGb-HK8L0xNKlab6EYY0iNMRV00RLbHlAbgKntj8pfD0Ox5y5AgqFNxJ1m2dWMoo_fsXiYNvAYN9DBLhewds1SsOQ4X7Q-7FCJKIceeiIOUbbpoCqJnxg_ZF-eukpA5QicuZv60qvbp-QBFt2x22TBIFtphJB-uNudY2_inRyt3VYZJGr-juUgxaMDTJ8WDiLyVqO_Dnd-vvU_Z0DF4xWiuVi5LVuYPO3etlT9ibfqJKne6Wf8bO2zQ7-A3KMgB1VY_fZmG0-13YHunTqGhIhLpkAqJJgcb8i3CQK0csGADE-_pLl7BwfbAq1WKAVtmU5QT-uAfvn1mjAv4Q6htO4wSzCW41Ij_i_VifLKZ8S_cZADmWxxBtWvwxgBfxIeoxY26zk0E63j6ZhmqVqM8bt-IRlm5Jfc1D3wWhZ9Tp-BGT4qZSmP2nVzyvyc8bE0wF2ANIF-Ks0Dh8KW9XRd_bma0BupJAHooAh5oFHhvr8qThWYGRdY9E4Jk6XkTElVe9X8FpimkkEGyDMltmCScbYDR3QGsHURbkBHYcQ1u6nb87PravJrBCd9Lw62P0ImdSOzHKmgM2xDkh7M0taCG_7kM5sJDplhJD14Oiz3CxlOTwci4TRr9kICpkdp0kr10xvQi_x_xTuxUynlKHl4OvyQ7RksdB39w1be4NRo4wYfbzAjGdK_KUwdQSJwyAK4wh6SKFnc8TfaVyqp4fy_drb_TAxH7nyHkeS0m9FRZOjaYmXNko0dX8_djS7hVdxcdjLpX50r9duN2kJ35cMbszsRyhnXr4JuIdVziEvSRs23jKgDwKXFld7uvV6QPTa6eEctpJXTlUSNZMhJxEfT-pO6Dbmu5oIYzus5ogQRqlohHyVOOndFhhR2T4MgxVczLc7Nu_M955mnNdGn6Dwz_kClAMOxCkLB6HuGF5pjoTb4UJcL93LP0Hw7FiKoaBectNrQPEyk-c2ycY2rFuoyuvNYdBBo-FPnTpP2O89mjkhL8-9RcFmKxN7UHniK2WDdu0uR0y3icm6zH8ABAZsduy8mhyDqx2YNQjhy5tfmoxkAIVUsL9YAt1o45wenfI1dW_p4bnxxEGVl3mUbRBswN8wc3CuwsxcWRNRAVZWC2WADLqgMUkInXDyLcijfoJ1LNxCo_6og8UIMKb7ix6uao4VSMnYO9mNE5SCq5jalPkjwhXfJiJL9RdRhB5rd5t3Dw7OrJwvcSY1EwVMT7z-l-6Zv-q7Q73NlzHU6Spx1AwrKx3fAIEX_LRULI-15Zsp4QcFc4qtAkzw07CTGzcBPQD88zHq3VcL1zVzToFO4f-exWsg0QdXwdipI3EtV3M-DyKXvHYNBKcpeIG8h95_EfcXfWXxAszyGfCDdGY_bxOzi9seh0A5LP0b5ZJa3lwcFWYtMEGL0G3yNUse-Aoqr0mZtdslMiHk7LO__E7fb3we82QwA316JSf7VRhnqSZIo-EuvKF0F2J2wmWea99bbD6wZPvJ6DD5YPfnTZ6ApXiJhnt8M5FCbjqefT3mwMhiMEVVFwKqqR8nH73NJtfz_lnfrWKRJ14_MohDCXFCluFWmSWyJ19e_co7of-_H7BrYBog9jmuJCFw4a2dUcE1tffnDI-sbsP8YdwOZ-RX6cEmllnCyhRFiC8UXACRmo6Jnszuz4UgXnz_DzmNF_mxzLg2TJzF8GG-63C25xE-lA3iYABoMQiPus79ki8gqxx_JW1h2yph1sghDHyWnBYKM-Ev9iDLXBfIhW2J8DYEDCdSqQbw190-sQIN2D0QQI-CP1O3MXze-ZZ8sZD4BU9rjnMJzmP7P_HG7pH-UqSbb2fOG80tZksYicLK0FVx0hIzAiB57ZIKqTOIQ08LhgF98RRXEZ7M5oz4P4dg4vaWHiM7lD92lXraJQ1KZcgBCGDyCHQWPrBzmGi9TJKrgkQvJwYPaxT7AazSkWsMDE9tWHX0LN_3BS48-ntxWmzBP8ocYudCZUo7hS0V3AJ0-KS_BYLY5KM-MepF2BYnN_iPn_tfuuCyKho_lw6QeiyrnWK1Yz8IWSoPueJ-ME02YLX3P9KZmN3dOD8zIkbju03v4PxJSL5yLtgHwmjRkYQ.cjOvEX-7aFRdot2RsGMsT7sykvFcQPb73BRcWRYb7us\",\"scope\":\"openid profile email offline_access ui.read ui.admin ui.preferences.read ui.preferences.write authority:tenants.read authority:tenants.write authority:users.read authority:users.write authority:roles.read authority:roles.write authority:clients.read authority:clients.write authority:tokens.read authority:tokens.revoke authority:branding.read authority:branding.write authority.audit.read graph:read sbom:read scanner:read policy:read policy:simulate policy:author policy:review policy:approve policy:run policy:activate policy:audit policy:edit policy:operate policy:publish airgap:seal airgap:status:read orch:read orch:operate orch:quota analytics.read advisory:read advisory-ai:view advisory-ai:operate vex:read vexhub:read exceptions:read exceptions:approve aoc:verify findings:read release:read release:write release:publish scheduler:read scheduler:operate notify.viewer notify.operator notify.admin notify.escalate evidence:read export.viewer export.operator export.admin vuln:view vuln:investigate vuln:operate vuln:audit platform.context.read platform.context.write doctor:run doctor:admin ops.health integration:read integration:write integration:operate packs.read packs.write packs.run packs.approve registry.admin timeline:read timeline:write trust:read trust:write trust:admin signer:read signer:sign signer:rotate signer:admin\",\"expiresAtEpochMs\":1776243236072},\"identity\":{\"subject\":\"34e69e47d31647b8930744944f2fff70\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6Ikg4TkdITjJESUNPUlE5QUpGTUlFRzlXWVdTVVlSUUw0LVJXR0E5QlEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjI0NDczNiwiaWF0IjoxNzc2MjQxNDM2LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiMzRlNjllNDdkMzE2NDdiODkzMDc0NDk0NGYyZmZmNzAiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiIwMWIxY2NhYi1iYmM4LTRjZjQtOWZlOC0zOTMxYWQ3YTJkOWMiLCJhdF9oYXNoIjoiVVRmc3NvaWJkUTFEM29UTFphMnlnZyJ9.ZWgl9L3OfXRvrrRsuHaaMXM-GVyYWjnF0PKI2Z4Q3xaCHJVY4dnvs54bBhjqYYWiaq9naM2KdLOTc3_KcAyiTPkqNbQPmHbxvfOAgYMt6Y1Og3lhcuuK2Lx9ZAIKBTlHK-QwaGANhOJ55oc9-JXsYKZHcQFMn-N61USb1fFz87ETzYfwBncYIDSCiYH3imu4uKrjvtgJ3xq6RTkKoccWuEs3cIyfc2xVC5sIk333tParluN983CyRe6qjMnFq336DzfNB8oGW3qVNuXfZaVyzABdrHyWXrwkTg_6wbPwTFHX1TEFOcszKEWV3SP4Pb8Sp8HuqxoLdMxdrLyQX_E-CQ\"},\"dpopKeyThumbprint\":\"DMsuRsgxj4LVVAKUpzryYlk0KRfhmt92uKKrhB36dmM\",\"issuedAtEpochMs\":1776241436074,\"tenantId\":\"demo-prod\",\"scopes\":[\"advisory-ai:operate\",\"advisory-ai:view\",\"advisory:read\",\"airgap:seal\",\"airgap:status:read\",\"analytics.read\",\"aoc:verify\",\"authority.audit.read\",\"authority:branding.read\",\"authority:branding.write\",\"authority:clients.read\",\"authority:clients.write\",\"authority:roles.read\",\"authority:roles.write\",\"authority:tenants.read\",\"authority:tenants.write\",\"authority:tokens.read\",\"authority:tokens.revoke\",\"authority:users.read\",\"authority:users.write\",\"doctor:admin\",\"doctor:run\",\"email\",\"evidence:read\",\"exceptions:approve\",\"exceptions:read\",\"export.admin\",\"export.operator\",\"export.viewer\",\"findings:read\",\"graph:read\",\"integration:operate\",\"integration:read\",\"integration:write\",\"notify.admin\",\"notify.escalate\",\"notify.operator\",\"notify.viewer\",\"offline_access\",\"openid\",\"ops.health\",\"orch:operate\",\"orch:quota\",\"orch:read\",\"packs.approve\",\"packs.read\",\"packs.run\",\"packs.write\",\"platform.context.read\",\"platform.context.write\",\"policy:activate\",\"policy:approve\",\"policy:audit\",\"policy:author\",\"policy:edit\",\"policy:operate\",\"policy:publish\",\"policy:read\",\"policy:review\",\"policy:run\",\"policy:simulate\",\"profile\",\"registry.admin\",\"release:publish\",\"release:read\",\"release:write\",\"sbom:read\",\"scanner:read\",\"scheduler:operate\",\"scheduler:read\",\"signer:admin\",\"signer:read\",\"signer:rotate\",\"signer:sign\",\"timeline:read\",\"timeline:write\",\"trust:admin\",\"trust:read\",\"trust:write\",\"ui.admin\",\"ui.preferences.read\",\"ui.preferences.write\",\"ui.read\",\"vex:read\",\"vexhub:read\",\"vuln:audit\",\"vuln:investigate\",\"vuln:operate\",\"vuln:view\"],\"audiences\":[],\"authenticationTimeEpochMs\":1776241435000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IjdLUks4OUw1UTNESkVQR09IV1NPSDNMVDktTVdNWVVJRS1aSU1VX1EiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjU5NTA4OCwiaWF0IjoxNzc2NTkzMjg4LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiZTk1MGE0NGUtZmMyZC00YTJkLWFkNDAtM2YwMmVjYjRiNjQ2Iiwic3ViIjoiZjk0NWYwMDgxMWY0NGYwMDgwNTgyNjhhMjY0ZWQwMTUiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZWZhdWx0IiwiYXV0aF90aW1lIjoxNzc2NTkzMjcyLCJvaV9wcnN0Ijoic3RlbGxhLW9wcy11aSIsImNsaWVudF9pZCI6InN0ZWxsYS1vcHMtdWkifQ.UQHuPO8JY_GQUzB-pPcos1eZJqPcbl3BaygXNnGUdlL1tz4C5P9PkHEPGH1LyNrJuPIzPSLI8Jx9vbXOF5VlTo2qfb2-NvalYkmuz8RTxDoevWpOfaFtoZLqWuOMy198pC_HKpxw6LMe9OxwRtN7n6OHB1jqGZWCmlJvEkWLvrrCqhIpnvFLcuC6l1Q54S2DFTEw1ahMYKMMmwtAFqAnfY5IPIZAdVJ9t7Ax8-Jski3vteSf1z-YIrdpEzEUv-5SXqNsgeNhHcE7-cdujOb4CMJsK4cLvBBZd2miZBkbRHs9ass19hXFPxhv4PgjuyrD9FNy2xzvPevbc2ykuvf6hw\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiJZV0pPRVlCSzU3UEpSQTFTSFhFWkM3NEFRQktRWFdEQjZaWlVPV0dVIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.J7ia8dvkcB0Bs0Z7yx_-BwUPECUq397tiuUOpc-tGIdWSNs9CvHHRj_yPGlU06Fmpr1bkelR5wpD7jy_8f-xc1OZmOWVCk4qrJSoCB_VhA8M5rf28xbLswNhj2OhP5_Lj9b9obaqzWwpLNAPl4wDaJBgOPW5hYNoVsoDcAZH3DB4jeALVLu6J7B3q5BLNAw-QRIgaEF7z8uutLrvs8-Dv0PgI-XcEGKQonmlml079_5jKEkKdiEAVCionn-2ksFkvLcDhK8DkDuPTvieHmnnz6Oi55XlBjlOr6-w_zV_3VA7L0zHozTKDFMUaVPqpU2rZU1ggA-hGMkb1zoBddoYiw.yFzbv7Vg3lA28Fu7wpT0Vg.TgCK7wAm6_JSQgq5ZL2YGNfNRNbAfsjx2_8WqtNwjRFiXg-dJt3OrOIljaz8bGivi3QLBOuyCrG4z_UXBITf5gcWd--BlW_XG8tvRfyXRFp9JsJqWxFl4_CwNZZNBCQpZVAy8g_oNSDhQhOyCW_rKK12GuRRv7swXkJKqkwTBLmAcHP6u-ewPheFufWSqWtf_-l1JdvaM69GoSOeiU9fx9ZWZabq2bKu8v1CM5D9_xVqq-RzKNP_DefvAn-nsElnNmVaTlKNmnu1R3K93mKorvL6aOpE1QtEzAkPyzEu7vrV3bJcoVv8YKHnJKuO7zT6gXJe5WHtcJDgHGjdjQd_Ca-fQ2nDaDk7PXmbOL8gLOUZRf1duuN5DAvlKqCehMEil_luv9w9aUX7dgHgZq3cJu6hM68Gr_TuPdCpPlQauTEyO81dFMD4ACNTwDWrnHpL36ChOl4znQ_gXjUS07T3ls8cG4FFu3v84FDUSJBPDjUIFoNZ5aR2LHrR8K5JhROb4fwu4wQf_EQPeNBTnMfmm_TeeSJUGkx7U2vD2IAPm_r3UgAmt9lS2ry4t8Xk8Alzg32ijARHAC8Tgu301p6RH0MgmbllwGbNBH1AwTyabytngpfda0Nu37NzKPZHha4AdotX4GjVKBXqA0TRzmgQR9Y_crlmQbjdGNselt7DD_OUpVgIX6uU4pnf2YoiyhAE6LwmFvLyAElgEf7d2rYe1q_Nb_rYerSWf4E73I2nwlsHs7Rcq9C3_z2y5mb35bMLj8chOiRAlW7rY5g2G6ybwAEz0RiUgxgULk6VHbfZgAoBHnCG0yB6hjbYjIrpA3bg3LJhHPcZGER8kU6p9bAZx5zR7AQ9xoO0wrwTQiyuHFRgHct2YYQqvjewzw8oDRsjx_jiNKg38vyXgccZgCVgSjQF6-xQYu-6-GU0CgNzgjPdl9UuQW4cN_ewwb5S9MZWcMPNXGKsyuG_hDemD1-n3B2bXyx2RaXi8c_QRWVj8BMY0cmTBiAvm-dPacbj4Gqk1SU7sqR-yyAH9L9MkSx0ok9p7VvvwjbPmXSfY8Savvls0ziWJOld21vPKDVbKD8PVWDWOKTsSSGbWXIyJTSVWfULDk3i2UjysL5JOhtcZrKokj3ERHvZKHMNMqckHz_MM-nRfS6aItguhBz8anl73WRcE9vTDdmAUUjP-XFyb_BG7ZZ545CTR9UUB3LQAPbbMQkFpmSUtdGvb4lL2AOWfQNMY9dpCkC7SlS4XDYDYcKe5rzjbNhG3cHfgvPxFkyygj5-JZ3hjIPpqytBl2omD3IQ05uRTWcvPLPc22FVb2E7UTDzOFASWTyKbfT9lBFNDemOQrw5EtNUYuc5RPKxUx0Uj_NFWiXjuxTmjl1db3ka-wWwQIEuUlQ4XACo7tWgJQNHN9VbAIobImoOMRB4K4JNN9ekJ4R2Mn_Zcz8B85Zjxn1ajwtmUyTszCPpXKorRG3eMR1kPFJO5eoYWFs1TLlXIAQYtv9niv-NitzVoOmAYkcanVB0hfN9q-g8hCRV4YvgjJzFQtcKcKSkaTFMYuB2wNT0yfag_nSpZM15aClopt1aFcEb2BaLZ3KgHxiAnU-3M3FjIgp4PK4XbT-shJJO3EsYDRtFpYLQZSaWuIopd3PheQNOIQCX_-__giM7xB7zOTv5NUkO5kzDWxRdMtbxua7jf6Xh_R715K0feg7WXu_t0GI-0E1E5AhzIqfSHOn4LDqi4muG4TMLtAt7qHbHgLOHrGvWUTWm65rKWo3rSCH_bb8mM_qRq5wRrxNjgWP-389Z7w2uTwvuqHlyrk9_5F16zcTBFYsrdsyNpsdNetv0B9_ukaBR8pZhHmqcwjKN8mwBdcxk7aSieUhSzLQ5WyZoaV0i0JKHeGX9uhjQEzZ2PjzHmP0UUEqc_lxpxLIm67p7wkT-Qf988PwqzUOqNLbXy-7KHkB9HeJMxWHRpNTo85hsCw3580E7oC5je4rDmzPSb8IPgLylZzwT3zA9We4K2kJWxv14hPLPbbRn3R0bhmx3FrAjrfiC14Rc7mrMdFatWI5kWk9H-QHhlIdOhlfmGMDmZdgxecsQqYUNAp-S2KH97KX5G8UqSVPaT8VJWz6KIAegjlo4-mJDOmyhAYELlsX1eNceO8RsY1mreb0JSXxuE1L_E0KrqfXKlqaIxZptlwtbFYKUo0A9lhImct9W0CyzRUNoPSk9efy1RUIYMwITMyzhfSYWOBPqEH3O3fbS_TOG7K2BrLC5_0HpATFMp3kWIZIPREvGfwNSHUrMVhNdukewix3zxdfGRsE2bG1C2xBIWnRHsdKcZa_DoLf6EHomz9OlGnYsrqtBV3vB6MzDGgb4Es6A9HTxynhtEEaTeuO_BAEmGuPBYGmNfaE8cx37LmRL33nK9v9zQvlaqSmeJeE53G_tTNsv98aDR9dtWlJgsIU5U9lTwepYSz6unzUf3-e0yDO0sE1nmyGIqvknAO6bxhPfmTE9xDQTZyU0YVjAL6XfOeQidaconqfh9DEFfqKxfbskymACi2WSE_4YjJYlEw1gfn-w3t5yggj8mQ7jeH_rWY6mxb7kaNFvMoVjUaqaJxtoGZEsgQVd0K3eFoAMC4tfzbX9oGwKNr-27e_5DbugDqlunZLBchhlM5o5gsBQqv3-JNk69erVOKWctI79yTIIUoKWtxqlLMMVSo2dcIb2TthKyyk0XKnKs7nLxT5lSsOJ3K8qeA8bF8_ikEi9YLnp88EoQOp-O7VEQ6JOgDy9Kv_NlV_jYrBpjJZsNe2kGzaTpw0Nf7ncfLvc90CsdcWylJTN_s9do2vJtpP1Kwa-nc8hdLqTyrt5G_oImjy62qcvDWE-G6bLjLGXkIcmAE-Lic_AXk7Fy86u6fxKs3pSDQK03zKOmsethMJ3meOz6mmjH4e2kcsK8V1UVJtffbW0h1dhv9aT96ODpL50udZUkyyk_iJVnEqhFJ6-ayHBGUVjBHrK5T1FbG7P0PoI7uTHkpYnRkqr9LOUBBdtBE6W0evjgWLLlVVjvK-QyDaVmLzY5YsU_nHwHOUB0n-iqPbsgf6Pnu0-e7qf081jXSr7LRnt8lB2BY1CwGWdnDVdapM4vjVxa7Kg4thKbm_ktcwtPJAUiXn_JkV7OF6M4YX2-N32JN6-3EKW5e9wnig-xjo4XjNEKFQ5Ln40iK2KjKfkLBbyRmhE1v3d7YON-uIAff0yI2ip4X_nW-PTOydWFcsgRcGOUR4VArzfZHKl17J8fSwJM4EGfE56do70PaAUcy1yHZfklIlZ-dvUQJEqkY6zqMdeZGtI0JAaIBi5vnNiXFWhXf2jZ8t9MpHq37w96CguhnV4pDoT9W3MsOqiJxTC256FDj-zWbfx7FDDPJ-VmtDnJjY2SluPLR4YRwLVcNLlhbjzAv2qaw1TrmNh_TBNPs0qLypdRpKMYyrjaLtLRoEjkFfR8nmt_5DR8X6GgcU2O55lFEn8Uzz9LqeLeaWaGuHQJqFQboY8tdVHvV8R9ijTRzG-P3vSWX6K8F9Y7FAbm25MJwWEJf6VWaHLDKY-wxs6OPdSBOdK--zWfNeRHg4gCt_L1Rk0j81PslGKe71cthqy8E4yIJErXWczUtcKx0pT4gynkT0viifpvisyTeXpW9_0gTKG6b71FFConwwomUwpZpoY0nO7xc4PT07Ph6f4FpgjkOtIWCukBf-LXwhaio_bAYQL34GPFusr92AypxO_9ZHkcY-SYt3H02PkjdDazert9k_XCSkahdiWnmYtC-2yDY8we-H1OHD4XyQbb2ReMRo9hMSrWv3StwSlHDJO0FT_TSHzWJnRk2rJPpoxaCnY53zfCkzsiViVrE5m4Ys3pBQBpIUQFcUNqmEt3d6-vuissmQAsEb9oBpmWaqC3cGV-6qz-uFD47VUYii7_3HDxtkc23FbcItpLKn0ECL2bf8AVbmou7qwI4KBU3R_tSI-DQtlms1tSpA4Bs1X6Z30a4wsl1nn4DEHC2Ln4lJ6CKixZaElcHlueDL-bUo13X5onWnP3xuhMdBBBpQcR_UidK3WPNfOKdsrrSmit6zyLJHX4CXA07LC__BzW8ZFX2IHQiXsxbMD7CN8tyiayPi-iDj25No-bCvWLV0SRQf_rB2Gt0tvObDHr4gNW6hCI1KRaBlKVfh5y5XfrNu8eFJW0KAi1Cxl4IKBQooS7DgbVRdt17EuOeR9AHrd7h5TqtV2UL5GzH-_n_02CzU47pZ3CACHQfbXVWpW11-YQo112p0P1gXb_kgpsSfxktzg9RofQ6Y1uAX84AkFyUw3Y1T50MBZR27XNq7WA1ovhaheEqvgfDL-kmLfqBoQl6OZ5b6L433rC0HKRQV5JtKxoulOEckKGIL7NAss6-ogKq582M3rkMjFuppcpKKZR_ix8lhAXLzniJMHqpxnyhuUK5mMAG_CzOSTlL-YSL2VWjMs3gmzOjqTAcs-JiRMzD_eMEsCoLSZ_otth8Aw4_Cj6tISca62_OFNPGvtcGCuGeNDsIxmx2doWXJ65yuAR2BekymdBe1tTiUWE9FrUCXZt20DxZB4eVvOAYainfUwPR-GKhHQXSHqVLcg-O45BaUHJ1Se_eXEJy2fSNaKOjfD_M2XVSUR_xo0LC9nUGzVBmY.3_UfBuwJIBsAgxZEYYD1TG0u_JsZbiZDqPwdoP-3_8E\",\"scope\":\"openid profile email offline_access ui.read ui.admin ui.preferences.read ui.preferences.write authority:tenants.read authority:tenants.write authority:users.read authority:users.write authority:roles.read authority:roles.write authority:clients.read authority:clients.write authority:tokens.read authority:tokens.revoke authority:branding.read authority:branding.write authority.audit.read graph:read sbom:read scanner:read policy:read policy:simulate policy:author policy:review policy:approve policy:run policy:activate policy:audit policy:edit policy:operate policy:publish airgap:seal airgap:status:read orch:read orch:operate orch:quota analytics.read advisory:read advisory-ai:view advisory-ai:operate vex:read vexhub:read exceptions:read exceptions:approve aoc:verify findings:read release:read release:write release:publish scheduler:read scheduler:operate notify.viewer notify.operator notify.admin notify.escalate evidence:read export.viewer export.operator export.admin vuln:view vuln:investigate vuln:operate vuln:audit platform.context.read platform.context.write doctor:run doctor:admin ops.health integration:read integration:write integration:operate packs.read packs.write packs.run packs.approve registry.admin timeline:read timeline:write trust:read trust:write trust:admin signer:read signer:sign signer:rotate signer:admin\",\"expiresAtEpochMs\":1776595090118},\"identity\":{\"subject\":\"f945f00811f44f008058268a264ed015\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IjdLUks4OUw1UTNESkVQR09IV1NPSDNMVDktTVdNWVVJRS1aSU1VX1EiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjU5NjU4OCwiaWF0IjoxNzc2NTkzMjg4LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiZjk0NWYwMDgxMWY0NGYwMDgwNTgyNjhhMjY0ZWQwMTUiLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiIyNGNiYWZhNS03ZDNhLTQ0ZDMtODgzNy00NTIyYTQyOTk0NzUiLCJhdF9oYXNoIjoiSzZqRXhqdDFmMFZZVlVtbWF6T09JQSJ9.EcbkBfurdz6gfBT_5_TP6vz2aNARKP5BiEhDoBKkY4esokvWoCxPQfT6NozP4sEde-lofT4W1w1GNavRDO7QN51C6YFM25DplqcX_QWGC_UhinUd2w_WkNtzYRDjVdpTMI7gnEch77IZ0pKAKaSTNwSTLIeGG-q-SZr1M_HiIjbG0x2-kzwolGrXxVuA5XXQbWNoFW0W9PdFKpz6SNicVi_D3WM2rvRkSF_-gZ4byilC7uIZ-o45HllQceM1EAlUObQMG01b-XDMaFCAY243GY0NzRZ2pgvPD6X6SuZPtAAzBPWGm71EU2w_DyVlZt7hTGyKl-SGt_hwSrXMQ1oDdA\"},\"dpopKeyThumbprint\":\"knhtz_ieCuFgS2A6bYdUWWhbWQNMcly969VVWFBQoAA\",\"issuedAtEpochMs\":1776593289124,\"tenantId\":\"default\",\"scopes\":[\"advisory-ai:operate\",\"advisory-ai:view\",\"advisory:read\",\"airgap:seal\",\"airgap:status:read\",\"analytics.read\",\"aoc:verify\",\"authority.audit.read\",\"authority:branding.read\",\"authority:branding.write\",\"authority:clients.read\",\"authority:clients.write\",\"authority:roles.read\",\"authority:roles.write\",\"authority:tenants.read\",\"authority:tenants.write\",\"authority:tokens.read\",\"authority:tokens.revoke\",\"authority:users.read\",\"authority:users.write\",\"doctor:admin\",\"doctor:run\",\"email\",\"evidence:read\",\"exceptions:approve\",\"exceptions:read\",\"export.admin\",\"export.operator\",\"export.viewer\",\"findings:read\",\"graph:read\",\"integration:operate\",\"integration:read\",\"integration:write\",\"notify.admin\",\"notify.escalate\",\"notify.operator\",\"notify.viewer\",\"offline_access\",\"openid\",\"ops.health\",\"orch:operate\",\"orch:quota\",\"orch:read\",\"packs.approve\",\"packs.read\",\"packs.run\",\"packs.write\",\"platform.context.read\",\"platform.context.write\",\"policy:activate\",\"policy:approve\",\"policy:audit\",\"policy:author\",\"policy:edit\",\"policy:operate\",\"policy:publish\",\"policy:read\",\"policy:review\",\"policy:run\",\"policy:simulate\",\"profile\",\"registry.admin\",\"release:publish\",\"release:read\",\"release:write\",\"sbom:read\",\"scanner:read\",\"scheduler:operate\",\"scheduler:read\",\"signer:admin\",\"signer:read\",\"signer:rotate\",\"signer:sign\",\"timeline:read\",\"timeline:write\",\"trust:admin\",\"trust:read\",\"trust:write\",\"ui.admin\",\"ui.preferences.read\",\"ui.preferences.write\",\"ui.read\",\"vex:read\",\"vexhub:read\",\"vuln:audit\",\"vuln:investigate\",\"vuln:operate\",\"vuln:view\"],\"audiences\":[],\"authenticationTimeEpochMs\":1776593272000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" ], [ "stellaops:wasEverAuth", "true" + ], + [ + "stellaops.auth.login.fb523b4b-6b82-4856-8426-95227415ecff", + "{\"state\":\"fb523b4b-6b82-4856-8426-95227415ecff\",\"codeVerifier\":\"CRDqWUd4QlgZUrDJTjOS-kDJKp6k6-cV1VULgFxUnzg\",\"createdAtEpochMs\":1776593265039,\"returnUrl\":\"/\",\"nonce\":\"7e2ac1fd-3b29-47b2-9b79-60435839292f\"}" ] ] }, + "sessionStatus": { + "hasFullSession": true, + "hasSessionInfo": true + }, "events": { "consoleErrors": [], - "requestFailures": [], + "requestFailures": [ + { + "method": "GET", + "url": "https://stella-ops.local/connect/authorize?response_type=code&client_id=stella-ops-ui&redirect_uri=https%3A%2F%2Fstella-ops.local%2Fauth%2Fcallback&scope=openid+profile+email+offline_access+ui.read+ui.admin+ui.preferences.read+ui.preferences.write+authority%3Atenants.read+authority%3Atenants.write+authority%3Ausers.read+authority%3Ausers.write+authority%3Aroles.read+authority%3Aroles.write+authority%3Aclients.read+authority%3Aclients.write+authority%3Atokens.read+authority%3Atokens.revoke+authority%3Abranding.read+authority%3Abranding.write+authority.audit.read+graph%3Aread+sbom%3Aread+scanner%3Aread+policy%3Aread+policy%3Asimulate+policy%3Aauthor+policy%3Areview+policy%3Aapprove+policy%3Arun+policy%3Aactivate+policy%3Aaudit+policy%3Aedit+policy%3Aoperate+policy%3Apublish+airgap%3Aseal+airgap%3Astatus%3Aread+orch%3Aread+orch%3Aoperate+orch%3Aquota+analytics.read+advisory%3Aread+advisory-ai%3Aview+advisory-ai%3Aoperate+vex%3Aread+vexhub%3Aread+exceptions%3Aread+exceptions%3Aapprove+aoc%3Averify+findings%3Aread+release%3Aread+release%3Awrite+release%3Apublish+scheduler%3Aread+scheduler%3Aoperate+notify.viewer+notify.operator+notify.admin+notify.escalate+evidence%3Aread+export.viewer+export.operator+export.admin+vuln%3Aview+vuln%3Ainvestigate+vuln%3Aoperate+vuln%3Aaudit+platform.context.read+platform.context.write+doctor%3Arun+doctor%3Aadmin+ops.health+integration%3Aread+integration%3Awrite+integration%3Aoperate+packs.read+packs.write+packs.run+packs.approve+registry.admin+timeline%3Aread+timeline%3Awrite+trust%3Aread+trust%3Awrite+trust%3Aadmin+signer%3Aread+signer%3Asign+signer%3Arotate+signer%3Aadmin&state=fb523b4b-6b82-4856-8426-95227415ecff&nonce=7e2ac1fd-3b29-47b2-9b79-60435839292f&code_challenge=GYPWvjWHUsim-5XCdVNmPtj-Z0yIT8fw0t1bmtCz3iU&code_challenge_method=S256&audience=stella-ops-api&ui_return=%2F", + "error": "net::ERR_ABORTED", + "page": "https://stella-ops.local/welcome" + } + ], "responseErrors": [] }, - "statePath": "C:\\dev\\New folder\\git.stella-ops.org\\src\\Web\\StellaOps.Web\\output\\playwright\\live-frontdoor-auth-state.json" + "statePath": "C:\\dev\\New folder\\git.stella-ops.org\\src\\Web\\StellaOps.Web\\output\\playwright\\live-frontdoor-auth-state.json", + "screenshotPath": null } diff --git a/src/Web/StellaOps.Web/output/playwright/live-frontdoor-auth-state.json b/src/Web/StellaOps.Web/output/playwright/live-frontdoor-auth-state.json index 6466850fc..67ee08786 100644 --- a/src/Web/StellaOps.Web/output/playwright/live-frontdoor-auth-state.json +++ b/src/Web/StellaOps.Web/output/playwright/live-frontdoor-auth-state.json @@ -4,33 +4,17 @@ { "origin": "https://stella-ops.local", "localStorage": [ + { + "name": "stellaops.auth.session.info", + "value": "{\"subject\":\"f945f00811f44f008058268a264ed015\",\"expiresAtEpochMs\":1776595090118,\"issuedAtEpochMs\":1776593289124,\"dpopKeyThumbprint\":\"knhtz_ieCuFgS2A6bYdUWWhbWQNMcly969VVWFBQoAA\",\"tenantId\":\"default\"}" + }, { "name": "stellaops.auth.session.full", - "value": "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6Ikg4TkdITjJESUNPUlE5QUpGTUlFRzlXWVdTVVlSUUw0LVJXR0E5QlEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjI0MzIzNiwiaWF0IjoxNzc2MjQxNDM2LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiZmZlZGY3MWQtYWY1MC00NWQ5LTlhMzQtMmNiYTE4ZTVmMWQyIiwic3ViIjoiMzRlNjllNDdkMzE2NDdiODkzMDc0NDk0NGYyZmZmNzAiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYyNDE0MzUsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.BAPTbUxstvf4uSVv4bcKBCxCWam0MHZ8KxaaqIygmYnTng7xnoN6x2ub6s0EjAbQRY7M67gP_ESywOOMkklH_iIXEixCEQLueAIyvbFmo21ssmDY2SclXtInuXsIosZfKpqraYcvn7nO9DdqDa44hZ6OVbFJTkrGjJCjazhApR5VD5hiAK53_swYhVPuPXCXNU38aExVPPazAu4C4QuDBJuy5Rp4tne92Uzo60tad-ojOMGT-7ILkDWqzp_SPRSuvbQuyzQEjBGGljSeoUqUnRg7Q4gj1u6XwyKMhTvbA6n6KtcgsPGLK6_AzspFqxOuMicjgcvY93pcnnm62b8EAg\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIxRVlZNFdJNFJfWE9HSDZVRFRPTFBUV0JQSE1QUlZaWURBS0FaRjcwIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.OjzFbXMVmR9utsZHxNNBb7lKfzW1tuD2V7uE6_WIo7viJTqvK5Pc70225amfOn_ppciNbsQtdWqtULoybzWVR-dOKJ7xN8vDcmhVJCvlHOTdVVZIw9fkdRDpsUXkabUFWC8hjpAd1ol-x5Y56EpB4LHmEBYRRV2g1g9lBMcnK8ARBoLwgrsK1xsR_Vueg9bvbcnbQdDoi_tgV2jORtPQ3WUyzNECt8WY0cMnU7AP43EcU5agg4r5SLJ4qYCoGRrEasAaH3kIEQaZLRqIlCNF1x-77vvMdYVDpqkLLgQF2bg2EM32_DIyccxSzdKFqyzTWieOfz8nnR_cgdpWITOjug.-ZgbI6MR19kz4G8ueQfOgg.w3F0J2tK722wQD6NcNcIrOXtj4ZkmYNy-mf-aK08l_TBUpHwqTByrAz3XfmD7SXtO4DqC0H-BdjxeBGbnnMxTjNG5BwtGN0wNZbYPd7yBm8eJy7ay6VhwpRBHDUm0UBUL-Onk0mcgD3vi_POkeBv54zFFJBqcijN3ia70Eim19HgxLkFop5LYebbWkX4juRRz6fI5KLglBrQnF6FTPaz3gq65PUbyAW1qQpdv1fw3n6S0YjkQzV_96sBsx7iLexfT16AwRRfmPiUOTpPljcfDtSHXKK4n0y4TVHdDb5FoOmf8WuloMAVPUzVjVuwJqZk169I8Yx-eyP62yWJYKNNaPE0-YQ9b7XXub2U3StSSMagPTNM8RG3Yxe2pnQDIoW5v81Q6Qdek7xktmooL8WNnFMBd4udNOsMCeGk98QTuXHXVVKq4zNuVuBgFoCWAWMBGGNVZXXtiELgwH3lE9IoUlbdMsGUBAQ-vcj_QFlzAGGonAp2YUMX3pY-bnqfzhp0cWMjBJxUK8-iRWmmw-1cMKtNSEqlg21bEDUQBFDJTMJENC31kaaqCfny8wNu90Oi9faTzx_bjAtFiH83XB1c-J0eTa5BBdWbd7Mu7U-hryne0RWK1wCkf97vo9aB0xclHxnQA2v-gtp-rtpb8QkvYS91D9YvpHyuPEhkQK3liyKRXvQND-6tMwDrcFoj9_7XyukAjw1WEKnjQG7u9TnH81ejB0nHVDOhwWGMxMIA8EO0_ql9MfGvIN3Cy_O82MlIthSn5-V7aakV_dyZYkvEcKZ0UBrSxCwQSKAS9cqmew0ud3fzzp8cAqwNMDHvkECw_YN8LBJN7FfpPXxnOsKveySv-IISsOxae9A5i9BPYh0OJ0jxKxI2XmnOqspdGZu-5D5JVZDBrqlDM4b84SECSuLnDkejV7_N1Cwt0YogU7lckvaFCvmuQ0xmhdWBOvlXtyEgGjr7HpviX_64utAR5ItsXu2QK0tVq_mmXiL9nNqsPqO13Qy2GJhtg_5GLXVV7GFztNVzaxu1Yu8tSEuhMWJ2aKx5xkaY5jr4pzW9gkgx-TQBQrkwSvKm2NVGxX74StxQwo-3vM0V8uUhlGxOBH2WNC8SbsPXdwsb3yad2c-0itweIm9znnGg7ePxl3NQFLVaBQiW1wiqJta5iSb970fTJ560wsNt7ooBDw2Ux5lGeEGNJC7F4X6KjuvZsONSJRkyguiduDVDytbN_PAvIGPPFsCNzdY3K9rw-fd3vABygfYWxhUacWTbHq-jFfYHijBJPQ4J7uzh-gr2O5dYODCg8uo3h1Ka-p9tXX1D_uLsfjHc62Sp3LaFZ34tFWzq3cZKKllmDWgpECgySFXLKHKRAP1GCahWkgyf3PW1j4liK3Xxaqq4W1-UokwOLyacWD5Gw54JgY2o43BpQZuK3pRjSaoyB2PErrNrzsdw9f_gHSa8-z7xvoQSjegyIjAB9UN0-h7pb-cozsYsvhsFm_4E7d6aCtmn80QQl5w7_8MyuuVngij65B8jRXxlUog-lQGSm-q3ZyMrWK8puR7KpokgfUl1qwOM1N-5WxDGHQHFeD2Hm-9mSmQfv3coF1rHmh65fk3kzubaMZoPEXFTtEwQtmhRVAS5F4JFniT_hX3xuthylEtW12b20EkLWfnSt_bH3tL0Ig48I4Z7P8w_v7kQNS8qjiAMaOstE48fOfc36y5Pk89uyDC_Zji2exOugPJ8E_YeaEhzhFeMHxwEq2JGWAzXwhma1wZ8BkNNWyMOLNhd5S0--OqnhArs09RCEpzpoWSNDa3aInE4QjNcEdQsMFyyCNa_1Pk9qXM8DLDPueh_BS7EhVhWNOoYLmBSZKFZHksB6LQngbWr9CS4RHedCw1zi5KriZKDSkLGwFrpBeXs2d2UGPqO-Wyz7ea6wtZ4MLWXpXJASlr0OYEEvR48DphIs--UPvTRf8pyg0O5ZBk45AwEl7twN85IYwlX01swbVe9V8Eur1hJBCKPUYn9WBs3SVP5wYURnO8ukOt2UIQCPzXG1qGTmGk88Df-TlsunUmVsHnPChzGxyew1FCwV4R1YDuc0BBd3XH1mlv2656lQ01Fht9l-gt06a2RwIJTZL4y1Vh3DYcvKWNBw-LLGjo7rOL8u8bADx_-cscu-Rs_n9PKFzuQfu5VZsRpMiIIJ8qnEqaHX5Mcy70gbRYH91mDXEdpAYykr4olwB1sG-yP5H10A7nKExx24YoToZbxgEyZuV7HZ5xrcreSIQ-uFH2S6I7nkYhm_3QshyHP1kn4UrUemrcVpAa97x8IUT6LSjJEQ6i6vH0akluHMFjPcf7o1UndrVUGOlux-kd3i7LD5Qp4x1fB3NTaOoPvsZGuBdTxLh5nxO55FU2afldTaTYVhgm9V3yrJ16p2wWj8cR8XbmGk-0ociK0FLjVgSVBK9oPX5OhMkYQYI0JQgdLfM_1PPvxBkJPU9Bv7OuVc3oFm9Vkf3CDgl2kNh9HN7Pi4eUDydqgwcO_WQqpLkbHV-V3IAMyxJRyvLBvNDkOLmyDzbg5CCUwVZuKugASUoud8qEqn-jupPGXxqzpUi7cBrgxM3CfULa3idzknLszw8K9utCjsazoyewSiWUN7V7L6b18Rp4gLMZ9M9NBRMHNa2Uf9htGb-HK8L0xNKlab6EYY0iNMRV00RLbHlAbgKntj8pfD0Ox5y5AgqFNxJ1m2dWMoo_fsXiYNvAYN9DBLhewds1SsOQ4X7Q-7FCJKIceeiIOUbbpoCqJnxg_ZF-eukpA5QicuZv60qvbp-QBFt2x22TBIFtphJB-uNudY2_inRyt3VYZJGr-juUgxaMDTJ8WDiLyVqO_Dnd-vvU_Z0DF4xWiuVi5LVuYPO3etlT9ibfqJKne6Wf8bO2zQ7-A3KMgB1VY_fZmG0-13YHunTqGhIhLpkAqJJgcb8i3CQK0csGADE-_pLl7BwfbAq1WKAVtmU5QT-uAfvn1mjAv4Q6htO4wSzCW41Ij_i_VifLKZ8S_cZADmWxxBtWvwxgBfxIeoxY26zk0E63j6ZhmqVqM8bt-IRlm5Jfc1D3wWhZ9Tp-BGT4qZSmP2nVzyvyc8bE0wF2ANIF-Ks0Dh8KW9XRd_bma0BupJAHooAh5oFHhvr8qThWYGRdY9E4Jk6XkTElVe9X8FpimkkEGyDMltmCScbYDR3QGsHURbkBHYcQ1u6nb87PravJrBCd9Lw62P0ImdSOzHKmgM2xDkh7M0taCG_7kM5sJDplhJD14Oiz3CxlOTwci4TRr9kICpkdp0kr10xvQi_x_xTuxUynlKHl4OvyQ7RksdB39w1be4NRo4wYfbzAjGdK_KUwdQSJwyAK4wh6SKFnc8TfaVyqp4fy_drb_TAxH7nyHkeS0m9FRZOjaYmXNko0dX8_djS7hVdxcdjLpX50r9duN2kJ35cMbszsRyhnXr4JuIdVziEvSRs23jKgDwKXFld7uvV6QPTa6eEctpJXTlUSNZMhJxEfT-pO6Dbmu5oIYzus5ogQRqlohHyVOOndFhhR2T4MgxVczLc7Nu_M955mnNdGn6Dwz_kClAMOxCkLB6HuGF5pjoTb4UJcL93LP0Hw7FiKoaBectNrQPEyk-c2ycY2rFuoyuvNYdBBo-FPnTpP2O89mjkhL8-9RcFmKxN7UHniK2WDdu0uR0y3icm6zH8ABAZsduy8mhyDqx2YNQjhy5tfmoxkAIVUsL9YAt1o45wenfI1dW_p4bnxxEGVl3mUbRBswN8wc3CuwsxcWRNRAVZWC2WADLqgMUkInXDyLcijfoJ1LNxCo_6og8UIMKb7ix6uao4VSMnYO9mNE5SCq5jalPkjwhXfJiJL9RdRhB5rd5t3Dw7OrJwvcSY1EwVMT7z-l-6Zv-q7Q73NlzHU6Spx1AwrKx3fAIEX_LRULI-15Zsp4QcFc4qtAkzw07CTGzcBPQD88zHq3VcL1zVzToFO4f-exWsg0QdXwdipI3EtV3M-DyKXvHYNBKcpeIG8h95_EfcXfWXxAszyGfCDdGY_bxOzi9seh0A5LP0b5ZJa3lwcFWYtMEGL0G3yNUse-Aoqr0mZtdslMiHk7LO__E7fb3we82QwA316JSf7VRhnqSZIo-EuvKF0F2J2wmWea99bbD6wZPvJ6DD5YPfnTZ6ApXiJhnt8M5FCbjqefT3mwMhiMEVVFwKqqR8nH73NJtfz_lnfrWKRJ14_MohDCXFCluFWmSWyJ19e_co7of-_H7BrYBog9jmuJCFw4a2dUcE1tffnDI-sbsP8YdwOZ-RX6cEmllnCyhRFiC8UXACRmo6Jnszuz4UgXnz_DzmNF_mxzLg2TJzF8GG-63C25xE-lA3iYABoMQiPus79ki8gqxx_JW1h2yph1sghDHyWnBYKM-Ev9iDLXBfIhW2J8DYEDCdSqQbw190-sQIN2D0QQI-CP1O3MXze-ZZ8sZD4BU9rjnMJzmP7P_HG7pH-UqSbb2fOG80tZksYicLK0FVx0hIzAiB57ZIKqTOIQ08LhgF98RRXEZ7M5oz4P4dg4vaWHiM7lD92lXraJQ1KZcgBCGDyCHQWPrBzmGi9TJKrgkQvJwYPaxT7AazSkWsMDE9tWHX0LN_3BS48-ntxWmzBP8ocYudCZUo7hS0V3AJ0-KS_BYLY5KM-MepF2BYnN_iPn_tfuuCyKho_lw6QeiyrnWK1Yz8IWSoPueJ-ME02YLX3P9KZmN3dOD8zIkbju03v4PxJSL5yLtgHwmjRkYQ.cjOvEX-7aFRdot2RsGMsT7sykvFcQPb73BRcWRYb7us\",\"scope\":\"openid profile email offline_access ui.read ui.admin ui.preferences.read ui.preferences.write authority:tenants.read authority:tenants.write authority:users.read authority:users.write authority:roles.read authority:roles.write authority:clients.read authority:clients.write authority:tokens.read authority:tokens.revoke authority:branding.read authority:branding.write authority.audit.read graph:read sbom:read scanner:read policy:read policy:simulate policy:author policy:review policy:approve policy:run policy:activate policy:audit policy:edit policy:operate policy:publish airgap:seal airgap:status:read orch:read orch:operate orch:quota analytics.read advisory:read advisory-ai:view advisory-ai:operate vex:read vexhub:read exceptions:read exceptions:approve aoc:verify findings:read release:read release:write release:publish scheduler:read scheduler:operate notify.viewer notify.operator notify.admin notify.escalate evidence:read export.viewer export.operator export.admin vuln:view vuln:investigate vuln:operate vuln:audit platform.context.read platform.context.write doctor:run doctor:admin ops.health integration:read integration:write integration:operate packs.read packs.write packs.run packs.approve registry.admin timeline:read timeline:write trust:read trust:write trust:admin signer:read signer:sign signer:rotate signer:admin\",\"expiresAtEpochMs\":1776243236072},\"identity\":{\"subject\":\"34e69e47d31647b8930744944f2fff70\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6Ikg4TkdITjJESUNPUlE5QUpGTUlFRzlXWVdTVVlSUUw0LVJXR0E5QlEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjI0NDczNiwiaWF0IjoxNzc2MjQxNDM2LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiMzRlNjllNDdkMzE2NDdiODkzMDc0NDk0NGYyZmZmNzAiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiIwMWIxY2NhYi1iYmM4LTRjZjQtOWZlOC0zOTMxYWQ3YTJkOWMiLCJhdF9oYXNoIjoiVVRmc3NvaWJkUTFEM29UTFphMnlnZyJ9.ZWgl9L3OfXRvrrRsuHaaMXM-GVyYWjnF0PKI2Z4Q3xaCHJVY4dnvs54bBhjqYYWiaq9naM2KdLOTc3_KcAyiTPkqNbQPmHbxvfOAgYMt6Y1Og3lhcuuK2Lx9ZAIKBTlHK-QwaGANhOJ55oc9-JXsYKZHcQFMn-N61USb1fFz87ETzYfwBncYIDSCiYH3imu4uKrjvtgJ3xq6RTkKoccWuEs3cIyfc2xVC5sIk333tParluN983CyRe6qjMnFq336DzfNB8oGW3qVNuXfZaVyzABdrHyWXrwkTg_6wbPwTFHX1TEFOcszKEWV3SP4Pb8Sp8HuqxoLdMxdrLyQX_E-CQ\"},\"dpopKeyThumbprint\":\"DMsuRsgxj4LVVAKUpzryYlk0KRfhmt92uKKrhB36dmM\",\"issuedAtEpochMs\":1776241436074,\"tenantId\":\"demo-prod\",\"scopes\":[\"advisory-ai:operate\",\"advisory-ai:view\",\"advisory:read\",\"airgap:seal\",\"airgap:status:read\",\"analytics.read\",\"aoc:verify\",\"authority.audit.read\",\"authority:branding.read\",\"authority:branding.write\",\"authority:clients.read\",\"authority:clients.write\",\"authority:roles.read\",\"authority:roles.write\",\"authority:tenants.read\",\"authority:tenants.write\",\"authority:tokens.read\",\"authority:tokens.revoke\",\"authority:users.read\",\"authority:users.write\",\"doctor:admin\",\"doctor:run\",\"email\",\"evidence:read\",\"exceptions:approve\",\"exceptions:read\",\"export.admin\",\"export.operator\",\"export.viewer\",\"findings:read\",\"graph:read\",\"integration:operate\",\"integration:read\",\"integration:write\",\"notify.admin\",\"notify.escalate\",\"notify.operator\",\"notify.viewer\",\"offline_access\",\"openid\",\"ops.health\",\"orch:operate\",\"orch:quota\",\"orch:read\",\"packs.approve\",\"packs.read\",\"packs.run\",\"packs.write\",\"platform.context.read\",\"platform.context.write\",\"policy:activate\",\"policy:approve\",\"policy:audit\",\"policy:author\",\"policy:edit\",\"policy:operate\",\"policy:publish\",\"policy:read\",\"policy:review\",\"policy:run\",\"policy:simulate\",\"profile\",\"registry.admin\",\"release:publish\",\"release:read\",\"release:write\",\"sbom:read\",\"scanner:read\",\"scheduler:operate\",\"scheduler:read\",\"signer:admin\",\"signer:read\",\"signer:rotate\",\"signer:sign\",\"timeline:read\",\"timeline:write\",\"trust:admin\",\"trust:read\",\"trust:write\",\"ui.admin\",\"ui.preferences.read\",\"ui.preferences.write\",\"ui.read\",\"vex:read\",\"vexhub:read\",\"vuln:audit\",\"vuln:investigate\",\"vuln:operate\",\"vuln:view\"],\"audiences\":[],\"authenticationTimeEpochMs\":1776241435000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" - }, - { - "name": "stellaops.helper.preferences", - "value": "{\"dismissed\":false,\"tooltipsMuted\":false,\"mutedPages\":[],\"mutedTipIds\":[],\"seenPages\":[],\"tipIndex\":{},\"dismissedBanners\":[],\"seenHelpPages\":[],\"pageHelpOpen\":{},\"pageHelpDismissedGlobal\":false,\"pageHelpDismissedPages\":[]}" - }, - { - "name": "stellaops.content-width", - "value": "centered" - }, - { - "name": "stellaops.assistant.state", - "value": "{\"seenRoutes\":[],\"completedTours\":[],\"tipPositions\":{},\"dismissed\":false}" + "value": "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IjdLUks4OUw1UTNESkVQR09IV1NPSDNMVDktTVdNWVVJRS1aSU1VX1EiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjU5NTA4OCwiaWF0IjoxNzc2NTkzMjg4LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiZTk1MGE0NGUtZmMyZC00YTJkLWFkNDAtM2YwMmVjYjRiNjQ2Iiwic3ViIjoiZjk0NWYwMDgxMWY0NGYwMDgwNTgyNjhhMjY0ZWQwMTUiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZWZhdWx0IiwiYXV0aF90aW1lIjoxNzc2NTkzMjcyLCJvaV9wcnN0Ijoic3RlbGxhLW9wcy11aSIsImNsaWVudF9pZCI6InN0ZWxsYS1vcHMtdWkifQ.UQHuPO8JY_GQUzB-pPcos1eZJqPcbl3BaygXNnGUdlL1tz4C5P9PkHEPGH1LyNrJuPIzPSLI8Jx9vbXOF5VlTo2qfb2-NvalYkmuz8RTxDoevWpOfaFtoZLqWuOMy198pC_HKpxw6LMe9OxwRtN7n6OHB1jqGZWCmlJvEkWLvrrCqhIpnvFLcuC6l1Q54S2DFTEw1ahMYKMMmwtAFqAnfY5IPIZAdVJ9t7Ax8-Jski3vteSf1z-YIrdpEzEUv-5SXqNsgeNhHcE7-cdujOb4CMJsK4cLvBBZd2miZBkbRHs9ass19hXFPxhv4PgjuyrD9FNy2xzvPevbc2ykuvf6hw\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiJZV0pPRVlCSzU3UEpSQTFTSFhFWkM3NEFRQktRWFdEQjZaWlVPV0dVIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.J7ia8dvkcB0Bs0Z7yx_-BwUPECUq397tiuUOpc-tGIdWSNs9CvHHRj_yPGlU06Fmpr1bkelR5wpD7jy_8f-xc1OZmOWVCk4qrJSoCB_VhA8M5rf28xbLswNhj2OhP5_Lj9b9obaqzWwpLNAPl4wDaJBgOPW5hYNoVsoDcAZH3DB4jeALVLu6J7B3q5BLNAw-QRIgaEF7z8uutLrvs8-Dv0PgI-XcEGKQonmlml079_5jKEkKdiEAVCionn-2ksFkvLcDhK8DkDuPTvieHmnnz6Oi55XlBjlOr6-w_zV_3VA7L0zHozTKDFMUaVPqpU2rZU1ggA-hGMkb1zoBddoYiw.yFzbv7Vg3lA28Fu7wpT0Vg.TgCK7wAm6_JSQgq5ZL2YGNfNRNbAfsjx2_8WqtNwjRFiXg-dJt3OrOIljaz8bGivi3QLBOuyCrG4z_UXBITf5gcWd--BlW_XG8tvRfyXRFp9JsJqWxFl4_CwNZZNBCQpZVAy8g_oNSDhQhOyCW_rKK12GuRRv7swXkJKqkwTBLmAcHP6u-ewPheFufWSqWtf_-l1JdvaM69GoSOeiU9fx9ZWZabq2bKu8v1CM5D9_xVqq-RzKNP_DefvAn-nsElnNmVaTlKNmnu1R3K93mKorvL6aOpE1QtEzAkPyzEu7vrV3bJcoVv8YKHnJKuO7zT6gXJe5WHtcJDgHGjdjQd_Ca-fQ2nDaDk7PXmbOL8gLOUZRf1duuN5DAvlKqCehMEil_luv9w9aUX7dgHgZq3cJu6hM68Gr_TuPdCpPlQauTEyO81dFMD4ACNTwDWrnHpL36ChOl4znQ_gXjUS07T3ls8cG4FFu3v84FDUSJBPDjUIFoNZ5aR2LHrR8K5JhROb4fwu4wQf_EQPeNBTnMfmm_TeeSJUGkx7U2vD2IAPm_r3UgAmt9lS2ry4t8Xk8Alzg32ijARHAC8Tgu301p6RH0MgmbllwGbNBH1AwTyabytngpfda0Nu37NzKPZHha4AdotX4GjVKBXqA0TRzmgQR9Y_crlmQbjdGNselt7DD_OUpVgIX6uU4pnf2YoiyhAE6LwmFvLyAElgEf7d2rYe1q_Nb_rYerSWf4E73I2nwlsHs7Rcq9C3_z2y5mb35bMLj8chOiRAlW7rY5g2G6ybwAEz0RiUgxgULk6VHbfZgAoBHnCG0yB6hjbYjIrpA3bg3LJhHPcZGER8kU6p9bAZx5zR7AQ9xoO0wrwTQiyuHFRgHct2YYQqvjewzw8oDRsjx_jiNKg38vyXgccZgCVgSjQF6-xQYu-6-GU0CgNzgjPdl9UuQW4cN_ewwb5S9MZWcMPNXGKsyuG_hDemD1-n3B2bXyx2RaXi8c_QRWVj8BMY0cmTBiAvm-dPacbj4Gqk1SU7sqR-yyAH9L9MkSx0ok9p7VvvwjbPmXSfY8Savvls0ziWJOld21vPKDVbKD8PVWDWOKTsSSGbWXIyJTSVWfULDk3i2UjysL5JOhtcZrKokj3ERHvZKHMNMqckHz_MM-nRfS6aItguhBz8anl73WRcE9vTDdmAUUjP-XFyb_BG7ZZ545CTR9UUB3LQAPbbMQkFpmSUtdGvb4lL2AOWfQNMY9dpCkC7SlS4XDYDYcKe5rzjbNhG3cHfgvPxFkyygj5-JZ3hjIPpqytBl2omD3IQ05uRTWcvPLPc22FVb2E7UTDzOFASWTyKbfT9lBFNDemOQrw5EtNUYuc5RPKxUx0Uj_NFWiXjuxTmjl1db3ka-wWwQIEuUlQ4XACo7tWgJQNHN9VbAIobImoOMRB4K4JNN9ekJ4R2Mn_Zcz8B85Zjxn1ajwtmUyTszCPpXKorRG3eMR1kPFJO5eoYWFs1TLlXIAQYtv9niv-NitzVoOmAYkcanVB0hfN9q-g8hCRV4YvgjJzFQtcKcKSkaTFMYuB2wNT0yfag_nSpZM15aClopt1aFcEb2BaLZ3KgHxiAnU-3M3FjIgp4PK4XbT-shJJO3EsYDRtFpYLQZSaWuIopd3PheQNOIQCX_-__giM7xB7zOTv5NUkO5kzDWxRdMtbxua7jf6Xh_R715K0feg7WXu_t0GI-0E1E5AhzIqfSHOn4LDqi4muG4TMLtAt7qHbHgLOHrGvWUTWm65rKWo3rSCH_bb8mM_qRq5wRrxNjgWP-389Z7w2uTwvuqHlyrk9_5F16zcTBFYsrdsyNpsdNetv0B9_ukaBR8pZhHmqcwjKN8mwBdcxk7aSieUhSzLQ5WyZoaV0i0JKHeGX9uhjQEzZ2PjzHmP0UUEqc_lxpxLIm67p7wkT-Qf988PwqzUOqNLbXy-7KHkB9HeJMxWHRpNTo85hsCw3580E7oC5je4rDmzPSb8IPgLylZzwT3zA9We4K2kJWxv14hPLPbbRn3R0bhmx3FrAjrfiC14Rc7mrMdFatWI5kWk9H-QHhlIdOhlfmGMDmZdgxecsQqYUNAp-S2KH97KX5G8UqSVPaT8VJWz6KIAegjlo4-mJDOmyhAYELlsX1eNceO8RsY1mreb0JSXxuE1L_E0KrqfXKlqaIxZptlwtbFYKUo0A9lhImct9W0CyzRUNoPSk9efy1RUIYMwITMyzhfSYWOBPqEH3O3fbS_TOG7K2BrLC5_0HpATFMp3kWIZIPREvGfwNSHUrMVhNdukewix3zxdfGRsE2bG1C2xBIWnRHsdKcZa_DoLf6EHomz9OlGnYsrqtBV3vB6MzDGgb4Es6A9HTxynhtEEaTeuO_BAEmGuPBYGmNfaE8cx37LmRL33nK9v9zQvlaqSmeJeE53G_tTNsv98aDR9dtWlJgsIU5U9lTwepYSz6unzUf3-e0yDO0sE1nmyGIqvknAO6bxhPfmTE9xDQTZyU0YVjAL6XfOeQidaconqfh9DEFfqKxfbskymACi2WSE_4YjJYlEw1gfn-w3t5yggj8mQ7jeH_rWY6mxb7kaNFvMoVjUaqaJxtoGZEsgQVd0K3eFoAMC4tfzbX9oGwKNr-27e_5DbugDqlunZLBchhlM5o5gsBQqv3-JNk69erVOKWctI79yTIIUoKWtxqlLMMVSo2dcIb2TthKyyk0XKnKs7nLxT5lSsOJ3K8qeA8bF8_ikEi9YLnp88EoQOp-O7VEQ6JOgDy9Kv_NlV_jYrBpjJZsNe2kGzaTpw0Nf7ncfLvc90CsdcWylJTN_s9do2vJtpP1Kwa-nc8hdLqTyrt5G_oImjy62qcvDWE-G6bLjLGXkIcmAE-Lic_AXk7Fy86u6fxKs3pSDQK03zKOmsethMJ3meOz6mmjH4e2kcsK8V1UVJtffbW0h1dhv9aT96ODpL50udZUkyyk_iJVnEqhFJ6-ayHBGUVjBHrK5T1FbG7P0PoI7uTHkpYnRkqr9LOUBBdtBE6W0evjgWLLlVVjvK-QyDaVmLzY5YsU_nHwHOUB0n-iqPbsgf6Pnu0-e7qf081jXSr7LRnt8lB2BY1CwGWdnDVdapM4vjVxa7Kg4thKbm_ktcwtPJAUiXn_JkV7OF6M4YX2-N32JN6-3EKW5e9wnig-xjo4XjNEKFQ5Ln40iK2KjKfkLBbyRmhE1v3d7YON-uIAff0yI2ip4X_nW-PTOydWFcsgRcGOUR4VArzfZHKl17J8fSwJM4EGfE56do70PaAUcy1yHZfklIlZ-dvUQJEqkY6zqMdeZGtI0JAaIBi5vnNiXFWhXf2jZ8t9MpHq37w96CguhnV4pDoT9W3MsOqiJxTC256FDj-zWbfx7FDDPJ-VmtDnJjY2SluPLR4YRwLVcNLlhbjzAv2qaw1TrmNh_TBNPs0qLypdRpKMYyrjaLtLRoEjkFfR8nmt_5DR8X6GgcU2O55lFEn8Uzz9LqeLeaWaGuHQJqFQboY8tdVHvV8R9ijTRzG-P3vSWX6K8F9Y7FAbm25MJwWEJf6VWaHLDKY-wxs6OPdSBOdK--zWfNeRHg4gCt_L1Rk0j81PslGKe71cthqy8E4yIJErXWczUtcKx0pT4gynkT0viifpvisyTeXpW9_0gTKG6b71FFConwwomUwpZpoY0nO7xc4PT07Ph6f4FpgjkOtIWCukBf-LXwhaio_bAYQL34GPFusr92AypxO_9ZHkcY-SYt3H02PkjdDazert9k_XCSkahdiWnmYtC-2yDY8we-H1OHD4XyQbb2ReMRo9hMSrWv3StwSlHDJO0FT_TSHzWJnRk2rJPpoxaCnY53zfCkzsiViVrE5m4Ys3pBQBpIUQFcUNqmEt3d6-vuissmQAsEb9oBpmWaqC3cGV-6qz-uFD47VUYii7_3HDxtkc23FbcItpLKn0ECL2bf8AVbmou7qwI4KBU3R_tSI-DQtlms1tSpA4Bs1X6Z30a4wsl1nn4DEHC2Ln4lJ6CKixZaElcHlueDL-bUo13X5onWnP3xuhMdBBBpQcR_UidK3WPNfOKdsrrSmit6zyLJHX4CXA07LC__BzW8ZFX2IHQiXsxbMD7CN8tyiayPi-iDj25No-bCvWLV0SRQf_rB2Gt0tvObDHr4gNW6hCI1KRaBlKVfh5y5XfrNu8eFJW0KAi1Cxl4IKBQooS7DgbVRdt17EuOeR9AHrd7h5TqtV2UL5GzH-_n_02CzU47pZ3CACHQfbXVWpW11-YQo112p0P1gXb_kgpsSfxktzg9RofQ6Y1uAX84AkFyUw3Y1T50MBZR27XNq7WA1ovhaheEqvgfDL-kmLfqBoQl6OZ5b6L433rC0HKRQV5JtKxoulOEckKGIL7NAss6-ogKq582M3rkMjFuppcpKKZR_ix8lhAXLzniJMHqpxnyhuUK5mMAG_CzOSTlL-YSL2VWjMs3gmzOjqTAcs-JiRMzD_eMEsCoLSZ_otth8Aw4_Cj6tISca62_OFNPGvtcGCuGeNDsIxmx2doWXJ65yuAR2BekymdBe1tTiUWE9FrUCXZt20DxZB4eVvOAYainfUwPR-GKhHQXSHqVLcg-O45BaUHJ1Se_eXEJy2fSNaKOjfD_M2XVSUR_xo0LC9nUGzVBmY.3_UfBuwJIBsAgxZEYYD1TG0u_JsZbiZDqPwdoP-3_8E\",\"scope\":\"openid profile email offline_access ui.read ui.admin ui.preferences.read ui.preferences.write authority:tenants.read authority:tenants.write authority:users.read authority:users.write authority:roles.read authority:roles.write authority:clients.read authority:clients.write authority:tokens.read authority:tokens.revoke authority:branding.read authority:branding.write authority.audit.read graph:read sbom:read scanner:read policy:read policy:simulate policy:author policy:review policy:approve policy:run policy:activate policy:audit policy:edit policy:operate policy:publish airgap:seal airgap:status:read orch:read orch:operate orch:quota analytics.read advisory:read advisory-ai:view advisory-ai:operate vex:read vexhub:read exceptions:read exceptions:approve aoc:verify findings:read release:read release:write release:publish scheduler:read scheduler:operate notify.viewer notify.operator notify.admin notify.escalate evidence:read export.viewer export.operator export.admin vuln:view vuln:investigate vuln:operate vuln:audit platform.context.read platform.context.write doctor:run doctor:admin ops.health integration:read integration:write integration:operate packs.read packs.write packs.run packs.approve registry.admin timeline:read timeline:write trust:read trust:write trust:admin signer:read signer:sign signer:rotate signer:admin\",\"expiresAtEpochMs\":1776595090118},\"identity\":{\"subject\":\"f945f00811f44f008058268a264ed015\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IjdLUks4OUw1UTNESkVQR09IV1NPSDNMVDktTVdNWVVJRS1aSU1VX1EiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjU5NjU4OCwiaWF0IjoxNzc2NTkzMjg4LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiZjk0NWYwMDgxMWY0NGYwMDgwNTgyNjhhMjY0ZWQwMTUiLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiIyNGNiYWZhNS03ZDNhLTQ0ZDMtODgzNy00NTIyYTQyOTk0NzUiLCJhdF9oYXNoIjoiSzZqRXhqdDFmMFZZVlVtbWF6T09JQSJ9.EcbkBfurdz6gfBT_5_TP6vz2aNARKP5BiEhDoBKkY4esokvWoCxPQfT6NozP4sEde-lofT4W1w1GNavRDO7QN51C6YFM25DplqcX_QWGC_UhinUd2w_WkNtzYRDjVdpTMI7gnEch77IZ0pKAKaSTNwSTLIeGG-q-SZr1M_HiIjbG0x2-kzwolGrXxVuA5XXQbWNoFW0W9PdFKpz6SNicVi_D3WM2rvRkSF_-gZ4byilC7uIZ-o45HllQceM1EAlUObQMG01b-XDMaFCAY243GY0NzRZ2pgvPD6X6SuZPtAAzBPWGm71EU2w_DyVlZt7hTGyKl-SGt_hwSrXMQ1oDdA\"},\"dpopKeyThumbprint\":\"knhtz_ieCuFgS2A6bYdUWWhbWQNMcly969VVWFBQoAA\",\"issuedAtEpochMs\":1776593289124,\"tenantId\":\"default\",\"scopes\":[\"advisory-ai:operate\",\"advisory-ai:view\",\"advisory:read\",\"airgap:seal\",\"airgap:status:read\",\"analytics.read\",\"aoc:verify\",\"authority.audit.read\",\"authority:branding.read\",\"authority:branding.write\",\"authority:clients.read\",\"authority:clients.write\",\"authority:roles.read\",\"authority:roles.write\",\"authority:tenants.read\",\"authority:tenants.write\",\"authority:tokens.read\",\"authority:tokens.revoke\",\"authority:users.read\",\"authority:users.write\",\"doctor:admin\",\"doctor:run\",\"email\",\"evidence:read\",\"exceptions:approve\",\"exceptions:read\",\"export.admin\",\"export.operator\",\"export.viewer\",\"findings:read\",\"graph:read\",\"integration:operate\",\"integration:read\",\"integration:write\",\"notify.admin\",\"notify.escalate\",\"notify.operator\",\"notify.viewer\",\"offline_access\",\"openid\",\"ops.health\",\"orch:operate\",\"orch:quota\",\"orch:read\",\"packs.approve\",\"packs.read\",\"packs.run\",\"packs.write\",\"platform.context.read\",\"platform.context.write\",\"policy:activate\",\"policy:approve\",\"policy:audit\",\"policy:author\",\"policy:edit\",\"policy:operate\",\"policy:publish\",\"policy:read\",\"policy:review\",\"policy:run\",\"policy:simulate\",\"profile\",\"registry.admin\",\"release:publish\",\"release:read\",\"release:write\",\"sbom:read\",\"scanner:read\",\"scheduler:operate\",\"scheduler:read\",\"signer:admin\",\"signer:read\",\"signer:rotate\",\"signer:sign\",\"timeline:read\",\"timeline:write\",\"trust:admin\",\"trust:read\",\"trust:write\",\"ui.admin\",\"ui.preferences.read\",\"ui.preferences.write\",\"ui.read\",\"vex:read\",\"vexhub:read\",\"vuln:audit\",\"vuln:investigate\",\"vuln:operate\",\"vuln:view\"],\"audiences\":[],\"authenticationTimeEpochMs\":1776593272000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" }, { "name": "stellaops.theme", "value": "system" - }, - { - "name": "stellaops.auth.session.info", - "value": "{\"subject\":\"34e69e47d31647b8930744944f2fff70\",\"expiresAtEpochMs\":1776243236072,\"issuedAtEpochMs\":1776241436074,\"dpopKeyThumbprint\":\"DMsuRsgxj4LVVAKUpzryYlk0KRfhmt92uKKrhB36dmM\",\"tenantId\":\"demo-prod\"}" - }, - { - "name": "stellaops.sidebar.preferences", - "value": "{\"sidebarCollapsed\":false,\"collapsedGroups\":[\"evidence\",\"setup-admin\"],\"collapsedSections\":[]}" } ] } diff --git a/src/Web/StellaOps.Web/package.json b/src/Web/StellaOps.Web/package.json index f16a01347..19e3bb7c9 100644 --- a/src/Web/StellaOps.Web/package.json +++ b/src/Web/StellaOps.Web/package.json @@ -19,6 +19,7 @@ "test:e2e": "playwright test", "test:e2e:search:live": "node ./scripts/run-live-search-e2e.mjs", "test:e2e:policy:producer:live": "node ./scripts/run-policy-orchestrator-proof-e2e.mjs", + "test:e2e:platform:bootstrap:first-run:live": "node ./scripts/live-setup-wizard-first-run-bootstrap.mjs", "test:e2e:live:auth": "node ./scripts/live-frontdoor-auth.mjs", "test:e2e:live:changed-surfaces": "node ./scripts/live-frontdoor-changed-surfaces.mjs", "serve:test": "ng serve --configuration development --port 4400 --host 127.0.0.1 --ssl", diff --git a/src/Web/StellaOps.Web/probe-services.mjs b/src/Web/StellaOps.Web/probe-services.mjs index b95bb6618..7e332a811 100644 --- a/src/Web/StellaOps.Web/probe-services.mjs +++ b/src/Web/StellaOps.Web/probe-services.mjs @@ -1,8 +1,17 @@ import { chromium } from 'playwright'; const BASE = 'http://127.1.0.5'; +const USERNAME = process.env.STELLAOPS_FRONTDOOR_USERNAME?.trim() + || process.env.STELLAOPS_ADMIN_USER?.trim() + || 'admin'; +const PASSWORD = process.env.STELLAOPS_FRONTDOOR_PASSWORD?.trim() + || process.env.STELLAOPS_ADMIN_PASS?.trim(); (async () => { + if (!PASSWORD) { + throw new Error('Set STELLAOPS_FRONTDOOR_PASSWORD or STELLAOPS_ADMIN_PASS before running this script.'); + } + const browser = await chromium.launch({ headless: true }); const context = await browser.newContext({ ignoreHTTPSErrors: true }); const page = await context.newPage(); @@ -14,8 +23,8 @@ const BASE = 'http://127.1.0.5'; try { await signInBtn.click({ timeout: 5000 }); } catch {} await page.waitForTimeout(2000); try { - await page.locator('input[name="Username"], input[type="text"]').first().fill('admin', { timeout: 5000 }); - await page.locator('input[type="password"]').first().fill('Admin@Stella2026!'); + await page.locator('input[name="Username"], input[type="text"]').first().fill(USERNAME, { timeout: 5000 }); + await page.locator('input[type="password"]').first().fill(PASSWORD); await page.locator('button[type="submit"]').first().click(); await page.waitForTimeout(4000); } catch (e) { console.log('Login error: ' + e.message); } diff --git a/src/Web/StellaOps.Web/scan-pages.mjs b/src/Web/StellaOps.Web/scan-pages.mjs index eb1c05276..62e6b64f4 100644 --- a/src/Web/StellaOps.Web/scan-pages.mjs +++ b/src/Web/StellaOps.Web/scan-pages.mjs @@ -1,6 +1,11 @@ import { chromium } from 'playwright'; const BASE = 'http://127.1.0.5'; +const USERNAME = process.env.STELLAOPS_FRONTDOOR_USERNAME?.trim() + || process.env.STELLAOPS_ADMIN_USER?.trim() + || 'admin'; +const PASSWORD = process.env.STELLAOPS_FRONTDOOR_PASSWORD?.trim() + || process.env.STELLAOPS_ADMIN_PASS?.trim(); const routes = [ '/security', @@ -27,6 +32,10 @@ const routes = [ ]; (async () => { + if (!PASSWORD) { + throw new Error('Set STELLAOPS_FRONTDOOR_PASSWORD or STELLAOPS_ADMIN_PASS before running this script.'); + } + const browser = await chromium.launch({ headless: true }); const context = await browser.newContext({ ignoreHTTPSErrors: true }); const page = await context.newPage(); @@ -50,8 +59,8 @@ const routes = [ const usernameInput = page.locator('input[name="Username"], input[name="username"], input[type="text"]').first(); const passwordInput = page.locator('input[name="Password"], input[name="password"], input[type="password"]').first(); - await usernameInput.fill('admin', { timeout: 5000 }); - await passwordInput.fill('Admin@Stella2026!'); + await usernameInput.fill(USERNAME, { timeout: 5000 }); + await passwordInput.fill(PASSWORD); const loginBtn = page.locator('button[type="submit"], button:has-text("Log in"), button:has-text("Login"), button:has-text("Sign in")').first(); await loginBtn.click(); diff --git a/src/Web/StellaOps.Web/scripts/live-frontdoor-auth.mjs b/src/Web/StellaOps.Web/scripts/live-frontdoor-auth.mjs index 73342df2c..49f3863ee 100644 --- a/src/Web/StellaOps.Web/scripts/live-frontdoor-auth.mjs +++ b/src/Web/StellaOps.Web/scripts/live-frontdoor-auth.mjs @@ -12,12 +12,19 @@ const webRoot = path.resolve(__dirname, '..'); const outputDirectory = path.join(webRoot, 'output', 'playwright'); const DEFAULT_BASE_URL = process.env.STELLAOPS_FRONTDOOR_BASE_URL?.trim() || 'https://stella-ops.local'; -const DEFAULT_USERNAME = process.env.STELLAOPS_FRONTDOOR_USERNAME?.trim() || 'admin'; -const DEFAULT_PASSWORD_CANDIDATES = process.env.STELLAOPS_FRONTDOOR_PASSWORD?.trim() - ? [process.env.STELLAOPS_FRONTDOOR_PASSWORD.trim()] - : ['Admin@Stella2026!', 'Admin@Stella1']; +const DEFAULT_USERNAME = process.env.STELLAOPS_FRONTDOOR_USERNAME?.trim() + || process.env.STELLAOPS_ADMIN_USER?.trim() + || 'admin'; +const DEFAULT_PASSWORD = process.env.STELLAOPS_FRONTDOOR_PASSWORD?.trim() + || process.env.STELLAOPS_ADMIN_PASS?.trim(); const DEFAULT_STATE_PATH = path.join(outputDirectory, 'live-frontdoor-auth-state.json'); const DEFAULT_REPORT_PATH = path.join(outputDirectory, 'live-frontdoor-auth-report.json'); +const DEFAULT_FAILURE_SCREENSHOT_PATH = path.join(outputDirectory, 'live-frontdoor-auth-failure.png'); + +function isAuthorityNavigationUrl(url) { + return typeof url === 'string' + && (url.includes('/connect/authorize') || url.includes('/auth/callback')); +} function createLocator(page, selectors) { return page.locator(selectors.join(', ')).first(); @@ -63,7 +70,7 @@ async function waitForShell(page) { async function waitForAuthTransition(page, usernameField, passwordField, timeoutMs = 10_000) { await Promise.race([ - page.waitForURL((url) => url.toString().includes('/connect/authorize') || url.toString().includes('/auth/callback'), { + page.waitForURL((url) => isAuthorityNavigationUrl(url.toString()), { timeout: timeoutMs, }).catch(() => {}), usernameField.waitFor({ state: 'visible', timeout: timeoutMs }).catch(() => {}), @@ -89,29 +96,145 @@ async function hasBrowserSession(page) { ).catch(() => false); } +async function waitForAuthenticationSurface(page, usernameField, passwordField, timeoutMs = 15_000) { + await Promise.race([ + page.waitForURL((url) => isAuthorityNavigationUrl(url.toString()), { + timeout: timeoutMs, + }).catch(() => {}), + usernameField.waitFor({ state: 'visible', timeout: timeoutMs }).catch(() => {}), + passwordField.waitFor({ state: 'visible', timeout: timeoutMs }).catch(() => {}), + page.waitForFunction( + () => + Boolean(sessionStorage.getItem('stellaops.auth.session.full')) + || Boolean(localStorage.getItem('stellaops.auth.session.info')) + || Boolean(localStorage.getItem('stellaops.auth.session.full')) + || Boolean(localStorage.getItem('stellaops.auth.session.info')), + null, + { + timeout: timeoutMs, + }, + ).catch(() => {}), + page.waitForTimeout(timeoutMs), + ]); +} + +async function waitForSignInTriggerOrAuthenticationSurface(page, signInTrigger, usernameField, passwordField, timeoutMs = 15_000) { + await Promise.race([ + waitForAuthenticationSurface(page, usernameField, passwordField, timeoutMs), + signInTrigger.waitFor({ state: 'visible', timeout: timeoutMs }).catch(() => {}), + page.waitForTimeout(timeoutMs), + ]); +} + async function ensureAuthorityLoginReachable(page, baseUrl, signInTrigger, usernameField, passwordField) { const hasLoginForm = async () => (await usernameField.count()) > 0 && (await passwordField.count()) > 0; - if (page.url().includes('/connect/authorize') || await hasLoginForm()) { + const hasAuthenticationSurface = async () => + isAuthorityNavigationUrl(page.url()) + || await hasLoginForm() + || await hasBrowserSession(page); + + if (await hasAuthenticationSurface()) { + return; + } + + await waitForSignInTriggerOrAuthenticationSurface(page, signInTrigger, usernameField, passwordField, 12_000); + + if (await hasAuthenticationSurface()) { return; } const clicked = await clickIfVisible(signInTrigger, 10_000); if (clicked) { - await waitForAuthTransition(page, usernameField, passwordField, 10_000); + await waitForAuthenticationSurface(page, usernameField, passwordField, 15_000); } - if (page.url().includes('/connect/authorize') || await hasLoginForm()) { + if (await hasAuthenticationSurface()) { return; } - await page.goto(`${baseUrl}/connect/authorize`, { + // The live frontdoor starts auth by redirecting from /welcome with OIDC parameters. + // Navigating to /connect/authorize directly produces an invalid_request page with no form. + await page.goto(`${baseUrl}/welcome`, { waitUntil: 'domcontentloaded', timeout: 30_000, }).catch(() => {}); - await waitForAuthTransition(page, usernameField, passwordField, 10_000); + + await waitForSignInTriggerOrAuthenticationSurface(page, signInTrigger, usernameField, passwordField, 15_000); + + if (await hasAuthenticationSurface()) { + return; + } + + const welcomeClicked = await clickIfVisible(signInTrigger, 10_000); + if (welcomeClicked) { + await waitForAuthenticationSurface(page, usernameField, passwordField, 15_000); + } +} + +async function collectReportData(page, context, events, statePath, options = {}) { + const screenshotPath = options.screenshotPath ?? null; + const storage = page + ? await page.evaluate(() => ({ + localStorageEntries: [...Array(localStorage.length)] + .map((_, index) => localStorage.key(index)) + .filter(Boolean) + .map((key) => [key, localStorage.getItem(key)]), + sessionStorageEntries: [...Array(sessionStorage.length)] + .map((_, index) => sessionStorage.key(index)) + .filter(Boolean) + .map((key) => [key, sessionStorage.getItem(key)]), + })).catch(() => ({ + localStorageEntries: [], + sessionStorageEntries: [], + })) + : { + localStorageEntries: [], + sessionStorageEntries: [], + }; + + const sessionStatus = page + ? await page.evaluate(() => ({ + hasFullSession: + Boolean(sessionStorage.getItem('stellaops.auth.session.full')) + || Boolean(localStorage.getItem('stellaops.auth.session.full')), + hasSessionInfo: + Boolean(sessionStorage.getItem('stellaops.auth.session.info')) + || Boolean(localStorage.getItem('stellaops.auth.session.info')), + })).catch(() => ({ + hasFullSession: false, + hasSessionInfo: false, + })) + : { + hasFullSession: false, + hasSessionInfo: false, + }; + + return { + authenticatedAtUtc: new Date().toISOString(), + authenticated: options.authenticated ?? sessionStatus.hasFullSession, + error: options.error ?? null, + baseUrl: options.baseUrl, + finalUrl: page?.url?.() ?? options.baseUrl, + title: page ? await page.title().catch(() => null) : null, + bodyText: page ? await page.locator('body').innerText().catch(() => null) : null, + cookies: context + ? (await context.cookies().catch(() => [])).map((cookie) => ({ + name: cookie.name, + domain: cookie.domain, + path: cookie.path, + secure: cookie.secure, + sameSite: cookie.sameSite, + })) + : [], + storage, + sessionStatus, + events, + statePath, + screenshotPath, + }; } export async function authenticateFrontdoor(options = {}) { @@ -121,21 +244,23 @@ export async function authenticateFrontdoor(options = {}) { ? options.passwordCandidates.map((value) => String(value ?? '').trim()).filter(Boolean) : options.password?.trim() ? [options.password.trim()] - : DEFAULT_PASSWORD_CANDIDATES; + : DEFAULT_PASSWORD + ? [DEFAULT_PASSWORD] + : []; const statePath = options.statePath || DEFAULT_STATE_PATH; const reportPath = options.reportPath || DEFAULT_REPORT_PATH; const headless = options.headless ?? true; + if (passwordCandidates.length === 0) { + throw new Error('Set STELLAOPS_FRONTDOOR_PASSWORD or STELLAOPS_ADMIN_PASS before authenticating against a live frontdoor.'); + } + mkdirSync(path.dirname(statePath), { recursive: true }); mkdirSync(path.dirname(reportPath), { recursive: true }); - const browser = await chromium.launch({ - headless, - args: ['--disable-dev-shm-usage'], - }); - - const context = await browser.newContext({ ignoreHTTPSErrors: true }); - const page = await context.newPage(); + let browser; + let context; + let page; const events = { consoleErrors: [], @@ -143,176 +268,187 @@ export async function authenticateFrontdoor(options = {}) { responseErrors: [], }; - page.on('console', (message) => { - if (message.type() === 'error') { - events.consoleErrors.push(message.text()); - } - }); - - page.on('requestfailed', (request) => { - const url = request.url(); - if (/\.(?:css|js|map|png|jpg|jpeg|svg|woff2?)(?:$|\?)/i.test(url)) { - return; - } - - events.requestFailures.push({ - method: request.method(), - url, - error: request.failure()?.errorText ?? 'unknown', - page: page.url(), + try { + browser = await chromium.launch({ + headless, + // Local browser automation must tolerate dev/self-signed certificates. + // Product runtime source sync remains strict about TLS validation. + args: ['--disable-dev-shm-usage', '--ignore-certificate-errors'], }); - }); - page.on('response', (response) => { - const url = response.url(); - if (/\.(?:css|js|map|png|jpg|jpeg|svg|woff2?)(?:$|\?)/i.test(url)) { - return; - } + context = await browser.newContext({ ignoreHTTPSErrors: true }); + page = await context.newPage(); - if (response.status() >= 400) { - events.responseErrors.push({ - status: response.status(), - method: response.request().method(), + page.on('console', (message) => { + if (message.type() === 'error') { + events.consoleErrors.push(message.text()); + } + }); + + page.on('requestfailed', (request) => { + const url = request.url(); + if (/\.(?:css|js|map|png|jpg|jpeg|svg|woff2?)(?:$|\?)/i.test(url)) { + return; + } + + events.requestFailures.push({ + method: request.method(), url, + error: request.failure()?.errorText ?? 'unknown', page: page.url(), }); - } - }); + }); - await page.goto(`${baseUrl}/welcome`, { - waitUntil: 'domcontentloaded', - timeout: 30_000, - }); - await page.waitForTimeout(1_500); + page.on('response', (response) => { + const url = response.url(); + if (/\.(?:css|js|map|png|jpg|jpeg|svg|woff2?)(?:$|\?)/i.test(url)) { + return; + } - const signInTrigger = createLocator(page, [ - 'button:has-text("Sign In")', - 'button:has-text("Sign in")', - 'a:has-text("Sign In")', - 'a:has-text("Sign in")', - 'button.cta', - ]); + if (response.status() >= 400) { + events.responseErrors.push({ + status: response.status(), + method: response.request().method(), + url, + page: page.url(), + }); + } + }); - const usernameField = createLocator(page, [ - 'input[name="username"]', - 'input[name="Username"]', - 'input[type="text"]', - 'input[type="email"]', - ]); - const passwordField = createLocator(page, [ - 'input[name="password"]', - 'input[name="Password"]', - 'input[type="password"]', - ]); + await page.goto(`${baseUrl}/welcome`, { + waitUntil: 'domcontentloaded', + timeout: 30_000, + }); - await ensureAuthorityLoginReachable(page, baseUrl, signInTrigger, usernameField, passwordField); - - const hasLoginForm = (await usernameField.count()) > 0 && (await passwordField.count()) > 0; - if (page.url().includes('/connect/authorize') || hasLoginForm) { - await Promise.all([ - usernameField.waitFor({ state: 'visible', timeout: 10_000 }).catch(() => {}), - passwordField.waitFor({ state: 'visible', timeout: 10_000 }).catch(() => {}), - ]); - - const filledUser = await fillIfVisible(usernameField, username); - if (!filledUser) { - throw new Error(`Authority login form was reached at ${page.url()} but the credentials fields were not interactable.`); - } - - const submitButton = createLocator(page, [ - 'button[type="submit"]', + const signInTrigger = createLocator(page, [ 'button:has-text("Sign In")', 'button:has-text("Sign in")', - 'button:has-text("Log in")', - 'button:has-text("Login")', + 'a:has-text("Sign In")', + 'a:has-text("Sign in")', + 'button.cta', ]); - let authenticated = false; - for (const candidate of passwordCandidates) { - const filledPassword = await fillIfVisible(passwordField, candidate); - if (!filledPassword) { - throw new Error(`Authority login form was reached at ${page.url()} but the password field was not interactable.`); - } + const usernameField = createLocator(page, [ + 'form input[name="username"]', + 'form input[name="Username"]', + 'input[name="username"]', + 'input[name="Username"]', + 'input[type="text"]', + 'input[type="email"]', + ]); + const passwordField = createLocator(page, [ + 'form input[name="password"]', + 'form input[name="Password"]', + 'input[name="password"]', + 'input[name="Password"]', + 'input[type="password"]', + ]); - await submitButton.click({ timeout: 10_000 }); + await ensureAuthorityLoginReachable(page, baseUrl, signInTrigger, usernameField, passwordField); + await waitForAuthenticationSurface(page, usernameField, passwordField, 15_000); - await Promise.race([ - page.waitForURL( - (url) => !url.toString().includes('/connect/authorize') && !url.toString().includes('/auth/callback'), - { timeout: 30_000 }, - ).catch(() => {}), - page.waitForFunction( - () => - Boolean(sessionStorage.getItem('stellaops.auth.session.full')) - || Boolean(localStorage.getItem('stellaops.auth.session.full')), - null, - { - timeout: 30_000, - }, - ).catch(() => {}), + const hasLoginForm = (await usernameField.count()) > 0 && (await passwordField.count()) > 0; + if (isAuthorityNavigationUrl(page.url()) || hasLoginForm) { + await Promise.all([ + usernameField.waitFor({ state: 'visible', timeout: 10_000 }).catch(() => {}), + passwordField.waitFor({ state: 'visible', timeout: 10_000 }).catch(() => {}), ]); - authenticated = await hasBrowserSession(page); - if (authenticated) { - break; + const filledUser = await fillIfVisible(usernameField, username); + if (!filledUser) { + throw new Error(`Authority login form was reached at ${page.url()} but the credentials fields were not interactable.`); } - if (!page.url().includes('/connect/authorize')) { - break; + const submitButton = createLocator(page, [ + 'form button[type="submit"]', + 'button[type="submit"]', + 'button:has-text("Sign In")', + 'button:has-text("Sign in")', + 'button:has-text("Log in")', + 'button:has-text("Login")', + ]); + + let authenticated = false; + for (const candidate of passwordCandidates) { + const filledPassword = await fillIfVisible(passwordField, candidate); + if (!filledPassword) { + throw new Error(`Authority login form was reached at ${page.url()} but the password field was not interactable.`); + } + + await submitButton.click({ timeout: 10_000 }); + + await Promise.race([ + page.waitForURL( + (url) => !isAuthorityNavigationUrl(url.toString()), + { timeout: 30_000 }, + ).catch(() => {}), + page.waitForFunction( + () => + Boolean(sessionStorage.getItem('stellaops.auth.session.full')) + || Boolean(localStorage.getItem('stellaops.auth.session.full')), + null, + { + timeout: 30_000, + }, + ).catch(() => {}), + ]); + + authenticated = await hasBrowserSession(page); + if (authenticated) { + break; + } + + if (!isAuthorityNavigationUrl(page.url())) { + break; + } } } + + await waitForShell(page); + await page.waitForTimeout(2_500); + + const sessionStatus = await page.evaluate(() => ({ + hasFullSession: + Boolean(sessionStorage.getItem('stellaops.auth.session.full')) + || Boolean(localStorage.getItem('stellaops.auth.session.full')), + hasSessionInfo: + Boolean(sessionStorage.getItem('stellaops.auth.session.info')) + || Boolean(localStorage.getItem('stellaops.auth.session.info')), + })); + const signInStillVisible = await signInTrigger.isVisible().catch(() => false); + if (!sessionStatus.hasFullSession) { + throw new Error( + `Frontdoor authentication did not establish a Stella Ops session. finalUrl=${page.url()} signInVisible=${signInStillVisible}`, + ); + } + + await context.storageState({ path: statePath }); + + const report = await collectReportData(page, context, events, statePath, { + authenticated: true, + baseUrl, + }); + + writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`, 'utf8'); + return report; + } catch (error) { + const screenshotPath = page ? DEFAULT_FAILURE_SCREENSHOT_PATH : null; + if (page && screenshotPath) { + await page.screenshot({ path: screenshotPath, fullPage: true }).catch(() => {}); + } + + const failureReport = await collectReportData(page, context, events, statePath, { + authenticated: false, + baseUrl, + error: error instanceof Error ? error.message : String(error), + screenshotPath, + }); + + writeFileSync(reportPath, `${JSON.stringify(failureReport, null, 2)}\n`, 'utf8'); + throw error; + } finally { + await browser?.close().catch(() => {}); } - - await waitForShell(page); - await page.waitForTimeout(2_500); - - const sessionStatus = await page.evaluate(() => ({ - hasFullSession: - Boolean(sessionStorage.getItem('stellaops.auth.session.full')) - || Boolean(localStorage.getItem('stellaops.auth.session.full')), - hasSessionInfo: - Boolean(sessionStorage.getItem('stellaops.auth.session.info')) - || Boolean(localStorage.getItem('stellaops.auth.session.info')), - })); - const signInStillVisible = await signInTrigger.isVisible().catch(() => false); - if (!sessionStatus.hasFullSession || (!page.url().includes('/connect/authorize') && signInStillVisible)) { - throw new Error( - `Frontdoor authentication did not establish a Stella Ops session. finalUrl=${page.url()} signInVisible=${signInStillVisible}`, - ); - } - - await context.storageState({ path: statePath }); - - const report = { - authenticatedAtUtc: new Date().toISOString(), - baseUrl, - finalUrl: page.url(), - title: await page.title(), - cookies: (await context.cookies()).map((cookie) => ({ - name: cookie.name, - domain: cookie.domain, - path: cookie.path, - secure: cookie.secure, - sameSite: cookie.sameSite, - })), - storage: await page.evaluate(() => ({ - localStorageEntries: [...Array(localStorage.length)] - .map((_, index) => localStorage.key(index)) - .filter(Boolean) - .map((key) => [key, localStorage.getItem(key)]), - sessionStorageEntries: [...Array(sessionStorage.length)] - .map((_, index) => sessionStorage.key(index)) - .filter(Boolean) - .map((key) => [key, sessionStorage.getItem(key)]), - })), - events, - statePath, - }; - - writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`, 'utf8'); - await browser.close(); - - return report; } export function getSessionStorageEntries(authReport) { diff --git a/src/Web/StellaOps.Web/src/app/core/api/policy-governance.client.ts b/src/Web/StellaOps.Web/src/app/core/api/policy-governance.client.ts index 7f50929bc..d798b0768 100644 --- a/src/Web/StellaOps.Web/src/app/core/api/policy-governance.client.ts +++ b/src/Web/StellaOps.Web/src/app/core/api/policy-governance.client.ts @@ -280,7 +280,7 @@ const MOCK_AUDIT_EVENTS: GovernanceAuditEvent[] = [ newState: { weight: 1.5 }, diff: { added: {}, removed: {}, modified: { weight: { before: 1.2, after: 1.5 } } }, traceId: 'trace-audit-001', - tenantId: 'demo-prod', + tenantId: 'default', }, { id: 'audit-002', @@ -292,7 +292,7 @@ const MOCK_AUDIT_EVENTS: GovernanceAuditEvent[] = [ targetResourceType: 'risk_profile', summary: 'Activated Strict Security Profile v1.1.0', traceId: 'trace-audit-002', - tenantId: 'demo-prod', + tenantId: 'default', }, { id: 'audit-003', @@ -306,7 +306,7 @@ const MOCK_AUDIT_EVENTS: GovernanceAuditEvent[] = [ previousState: { isSealed: false }, newState: { isSealed: true, reason: 'Air-gap deployment preparation' }, traceId: 'trace-audit-003', - tenantId: 'demo-prod', + tenantId: 'default', }, ]; @@ -1178,4 +1178,3 @@ export class HttpPolicyGovernanceApi implements PolicyGovernanceApi { } } - diff --git a/src/Web/StellaOps.Web/src/app/core/testing/dashboard-v3.component.spec.ts b/src/Web/StellaOps.Web/src/app/core/testing/dashboard-v3.component.spec.ts index b3f714f07..28ca316a4 100644 --- a/src/Web/StellaOps.Web/src/app/core/testing/dashboard-v3.component.spec.ts +++ b/src/Web/StellaOps.Web/src/app/core/testing/dashboard-v3.component.spec.ts @@ -254,4 +254,37 @@ describe('DashboardV3Component', () => { ), ).toBeTrue(); }); + + it('renders recommended next steps inside the dismissible dashboard banner', () => { + const contextStore = { + initialize: () => undefined, + initialized: () => true, + error: () => null, + tenantId: () => 'tenant-default', + selectedRegions: () => [], + selectedEnvironments: () => [], + contextVersion: () => 0, + environments: () => [ + { + environmentId: 'dev', + regionId: 'eu-west', + environmentType: 'development', + displayName: 'Development EU West', + }, + ], + }; + + TestBed.configureTestingModule({ + imports: [DashboardV3Component], + providers: provideDashboardDependencies(contextStore), + }); + + const fixture = TestBed.createComponent(DashboardV3Component); + fixture.detectChanges(); + + const host = fixture.nativeElement as HTMLElement; + expect(host.querySelector('.dashboard-next-steps')).toBeNull(); + expect(host.querySelector('.dashboard-banner__next-steps')).not.toBeNull(); + expect(host.textContent).toContain('What should I do next?'); + }); }); diff --git a/src/Web/StellaOps.Web/src/app/features/audit-log/audit-log-table.component.spec.ts b/src/Web/StellaOps.Web/src/app/features/audit-log/audit-log-table.component.spec.ts index eccc1ba49..679303bdb 100644 --- a/src/Web/StellaOps.Web/src/app/features/audit-log/audit-log-table.component.spec.ts +++ b/src/Web/StellaOps.Web/src/app/features/audit-log/audit-log-table.component.spec.ts @@ -4,7 +4,7 @@ */ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { RouterModule } from '@angular/router'; +import { ActivatedRoute, RouterModule, convertToParamMap } from '@angular/router'; import { of } from 'rxjs'; import { AuditLogTableComponent } from './audit-log-table.component'; import { AuditLogClient } from '../../core/api/audit-log.client'; @@ -27,7 +27,17 @@ describe('AuditLogTableComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ imports: [AuditLogTableComponent, RouterModule.forRoot([])], - providers: [{ provide: AuditLogClient, useValue: mockClient }], + providers: [ + { provide: AuditLogClient, useValue: mockClient }, + { + provide: ActivatedRoute, + useValue: { + snapshot: { + queryParamMap: convertToParamMap({}), + }, + }, + }, + ], }).compileComponents(); fixture = TestBed.createComponent(AuditLogTableComponent); @@ -101,4 +111,31 @@ describe('AuditLogTableComponent', () => { expect(component.formatModule('authority')).toBe('Authority'); expect(component.formatModule('jobengine')).toBe('JobEngine'); }); + + it('adds an integration resource filter pill when the audit view is scoped to a single integration', () => { + component.selectedModule = 'integrations'; + component.selectedResourceType = 'integration'; + component.selectedResourceId = 'int-1'; + component.selectedResourceName = 'Harbor Registry'; + + expect(component.buildFilters()).toEqual( + jasmine.objectContaining({ + modules: ['integrations'], + resourceType: 'integration', + resourceId: 'int-1', + }), + ); + + component['rebuildPills'](); + + expect(component.activeFilterPills()).toEqual( + jasmine.arrayContaining([ + jasmine.objectContaining({ + key: 'resource', + value: 'int-1', + label: 'Integration: Harbor Registry', + }), + ]), + ); + }); }); diff --git a/src/Web/StellaOps.Web/src/app/features/audit-log/audit-log-table.component.ts b/src/Web/StellaOps.Web/src/app/features/audit-log/audit-log-table.component.ts index 93a1a54b5..8742284ce 100644 --- a/src/Web/StellaOps.Web/src/app/features/audit-log/audit-log-table.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/audit-log/audit-log-table.component.ts @@ -19,6 +19,12 @@ import { FilterBarComponent, type FilterOption, type ActiveFilter } from '../../ Audit Log / All Events

Audit Events

+ @if (selectedResourceId) { +

+ Scoped to {{ resourceScopeLabel() }} + {{ selectedResourceName || selectedResourceId }} +

+ } ([]); ngOnInit(): void { - const moduleParam = this.route.snapshot.queryParamMap.get('module'); + const queryParams = this.route.snapshot.queryParamMap; + const moduleParam = queryParams.get('module'); if (moduleParam && this.allModules.includes(moduleParam as AuditModule)) { this.selectedModule = moduleParam; - this.rebuildPills(); } + this.selectedAction = queryParams.get('action') ?? ''; + this.selectedSeverity = queryParams.get('severity') ?? ''; + this.searchQuery = queryParams.get('search') ?? ''; + this.selectedResourceType = queryParams.get('resourceType') ?? ''; + this.selectedResourceId = queryParams.get('resourceId') ?? ''; + this.selectedResourceName = queryParams.get('resourceName') ?? ''; + this.rebuildPills(); this.loadEvents(); } @@ -512,6 +538,10 @@ export class AuditLogTableComponent implements OnInit { const prop = map[filter.key]; if (prop) { (this as any)[prop] = filter.key === 'dateRange' ? '7d' : ''; + } else if (filter.key === 'resource') { + this.selectedResourceType = ''; + this.selectedResourceId = ''; + this.selectedResourceName = ''; } this.rebuildPills(); this.applyFilters(); @@ -538,6 +568,8 @@ export class AuditLogTableComponent implements OnInit { if (this.selectedAction) filters.actions = [this.selectedAction as AuditAction]; if (this.selectedSeverity) filters.severities = [this.selectedSeverity as AuditSeverity]; if (this.searchQuery) filters.search = this.searchQuery; + if (this.selectedResourceType) filters.resourceType = this.selectedResourceType; + if (this.selectedResourceId) filters.resourceId = this.selectedResourceId; const now = new Date(); if (this.dateRange === '24h') { @@ -566,10 +598,25 @@ export class AuditLogTableComponent implements OnInit { this.selectedSeverity = ''; this.dateRange = '7d'; this.searchQuery = ''; + this.selectedResourceType = ''; + this.selectedResourceId = ''; + this.selectedResourceName = ''; this.activeFilterPills.set([]); this.applyFilters(); } + resourceScopeLabel(): string { + if (!this.selectedResourceType) { + return 'resource'; + } + + if (this.selectedResourceType === 'integration') { + return 'integration'; + } + + return this.selectedResourceType.replace(/[-_]+/g, ' ').toLowerCase(); + } + private rebuildPills(): void { const pills: ActiveFilter[] = []; const defs = [ @@ -585,6 +632,18 @@ export class AuditLogTableComponent implements OnInit { pills.push({ key: def.key, value: val, label: def.label + ': ' + (opt?.label || val) }); } } + if (this.selectedResourceId) { + const resourceTypeLabel = this.selectedResourceType + ? `${this.resourceScopeLabel().replace(/\b\w/g, (match) => match.toUpperCase())}: ` + : ''; + pills.push({ + key: 'resource', + value: this.selectedResourceId, + label: this.selectedResourceName + ? `${resourceTypeLabel}${this.selectedResourceName}` + : `${resourceTypeLabel}${this.selectedResourceId}`, + }); + } this.activeFilterPills.set(pills); } diff --git a/src/Web/StellaOps.Web/src/app/features/dashboard-v3/dashboard-v3.component.ts b/src/Web/StellaOps.Web/src/app/features/dashboard-v3/dashboard-v3.component.ts index e651aea12..fb39f0ecf 100644 --- a/src/Web/StellaOps.Web/src/app/features/dashboard-v3/dashboard-v3.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/dashboard-v3/dashboard-v3.component.ts @@ -132,6 +132,20 @@ interface DashboardGuideAction {
  • Medium Moderate risk. Address in planned sprint work.
  • Low Track and fix when it is cost-effective.
  • + @if (recommendedDashboardActions().length > 0 && !hasNoEnvironments()) { +
    + What should I do next? +

    These suggestions are based on the current state of your environments, feeds, and findings.

    +
    + @for (step of recommendedDashboardActions(); track step.id) { + + {{ step.title }} + {{ step.description }} + + } +
    +
    + }