diff --git a/src/Web/StellaOps.Web/angular.json b/src/Web/StellaOps.Web/angular.json index db81e7314..e0f37f72e 100644 --- a/src/Web/StellaOps.Web/angular.json +++ b/src/Web/StellaOps.Web/angular.json @@ -134,10 +134,13 @@ "runnerConfig": "vitest.active-surfaces.config.ts", "setupFiles": ["src/test-setup.ts"], "include": [ + "src/app/features/integration-hub/integration.service.spec.ts", + "src/app/features/integrations/integration-wizard.component.spec.ts", "src/tests/deployments/create-deployment.component.spec.ts", "src/tests/evidence/evidence-center-hub.component.spec.ts", "src/tests/graph_reachability_overlay/graph-canvas.component.spec.ts", "src/tests/graph_reachability_overlay/graph-overlays.component.spec.ts", + "src/tests/integration_hub/integration-onboarding-wizard.component.spec.ts", "src/tests/release-control/environment-detail-standardization.component.spec.ts", "src/tests/sprint309/security-vulnerability-detail-page.component.spec.ts", "src/tests/sprint309/signed-score-ribbon.component.spec.ts" 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 fd0a3bc70..47297fc4d 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,14 +1,14 @@ { - "authenticatedAtUtc": "2026-04-13T18:37:35.830Z", + "authenticatedAtUtc": "2026-04-14T04:55:25.696Z", "baseUrl": "https://stella-ops.local", - "finalUrl": "https://stella-ops.local/?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "finalUrl": "https://stella-ops.local/", "title": "Dashboard - StellaOps", "cookies": [], "storage": { "localStorageEntries": [ [ "stellaops.auth.session.full", - "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IjFKVkI4VVdCTkRUV0UxMTRTUlhLNEhMT0NDTU1HWFRKTExWRDZLOVgiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEwNzI1MywiaWF0IjoxNzc2MTA1NDUzLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiZTRiNGYyMzAtMjdmYy00OGM0LTllMmMtMTk0NTU4MmRiMWMyIiwic3ViIjoiMTk5ZTc3MTQ3YmI4NDVmYmFiOTQxNmNkYWZmNTk3MjYiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMDU0NTIsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.0pgGOI_zwY_SADTfCnH-VcYXfndryb_htp67MIiW0AG4zLMkGHoEkNs8HXIMxwhPN4LAP_kfpmiQn1zgJZA5nFcBfnzUlbOaIUqUWFpVuv8P-JQKd63LZ_q8LnAWnYsEKgIphpqCYHTOYgcOUkuxrAKkUyyXC3rpuIK48zVhzHpwDDTHPBRxq_ZIXOHhZJ0YvtxqwV-Kc1AO_ZD4D0fstTV2ffllBdbNsIqjuhumP6w2Ga168MJ2jAsmorJ4iGVj-aLkkDCI3wcS6Mb8NBtNmJv4alB0CGOv_159kZBVkhCYejtTSOEWgTfkmDozMRWg9JdGqtgEt73_cbU19L_WGg\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiJUWUtCWUlITVpFVFpYWlk3WllFQ1A0OVMyQ0ZKVElPVkIwWlFEX0tHIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.lAQkETzitD88nXcC-kfreQdLmDJKGuEZhALU_Vvt3WFHFjfkfvv08Kx55nCTQ63QXUcBkiLNZRY_0piiJ2_gPyb0U07ohwZfgRJHL_IjnvIXRY8_DvAVi_X1R8tUCixkSrpOcrlM7hNv9Z_pNKPRBsVGIPHQ2QemzJ8JrVgjVEUKMoB9IYAvf2JXkHefPWi-qZk-jo_apMABnFamd6WpZsA6WiKPPvzqc8X-cdJ9zQ5_GB5BKyp7PUzmxCAk5qUC9dKuBhUGP-RIVKbY7p2IZ1zfwRvhz0UlVZxl_wv2scwcc36rMeCz5fYRYZPdS3UWme8a1q9m3VxSOGUw82dOJQ.2OkN0F40NVGK46DCMv0ajg.da5uTUoxgxoYRONkKBd8Xz89h9zDQBqwWRHS62QkzhFHmI-p6WbTfIW3_3pGaJKxIi9EBVNZpSDF-YjV3AaCl28WwVDmuUkPWhLFW5826zJKb9p1l7IEr3DqHvY_zu2Z_W1c1wWUSU9KCVvNCGvzE_MzNaqUh1Se9-YPV2PKGjOBxp1tp7JUIlIAZB9oL0Kwat3z6Qhhaoci8t_cwrPi0CwlXJiKg0yCYYFtK84c7rWZkf4abhT5R33fHFy0R75z2r77tRNMhhHM6dqkcBYVzufw6rxxkUR26_lf4JrDagIhP3aqhjrUprPH8MOGN7PHqxEyxSfEqCB_l4S_grVcyYfFgMbO6H8gek0DA8W_d2zbXOiUbgLL7CbSfxyzs_wTGdLBiu18B3qapqkjRH_AkI4-ILitqh-n153p6KsBV4iJmyHo-if641tcHXoHtG0TJ1852wFa676WiAt1xCv6hdHsacTJZTrzojynmPkwlJrBdf_NydcJNPMICZNt5PXXgkaQu68fhw25XToaQcSKeeRhR2LWBLcZ_VYG3XtGPDAdSxKQEAy25KS-Obrn_SgkcOWrhb2RPHNNDxPfjmUOQDVS2S-Q3Q68NrMOspgjSQbVosnfiQImNSIF5CqjAHE4JXLpZuc0twsfplt0y9_RPtw8wkxR2H2eiNTsIRTo0vmXJMSWexNF_PA_SHhEMM9F_l7x2PHrWAVUBiEfdilakRQbF4eU0IzMSWLy_4ifHvcw4jRX1TkUch-c5ieuPQtnKP8H7HFI_Y1Wj6sTdKrys7S--2m84v0JYjMkUaNc3XiWr2jDE0J-j_TA17VlGnmF2qBkkNy9PEAvricM-emv4mejH0vA7NffKbN41lHflVeCppeXTWKJze-kJvQjJJoSL2OsVJFiscyyo0MfQAcIurtJ7wtWAzk0E10rYlvwXp0HHKMosaE7r_hcGjv-sSd6lscfk59fuGiSrzD5zJvwJRQdzhrsI8HFkRyUFtEkNoeROlrwzdj6IgDgz6T6vp7tuFPSkv4cEGQ1kfx3RUH0u7LVxZFA6Jev_22szOlS2RJ8rwT7Wnua9z96Qk58MYoq8r_mpBVGEr34hUIK9xJI5U8CclbJJlYmoeo9XsMEUz6gUG2ojDoUjYa8V-r1H-zXY8KA9_yAYjmGVQ9NsJZqidbZL_K07qi3C1yZ0RLMvVa2S15hXtYwFM0ZGKLcDkPqjCy6v9DFoKv2h-4fZL8HjYTfsFJYhWHgxSyL3-4Q7b0ZXRc_bdixGtAWhekKPtnKzrDohF2-2R3xFf8M2C1VUrRe8xcLdElZ2DpkYHrrzhZznVfP9kNskDRkwm1izCW5ICglVc75UQEQPF9AW39DED-vrqXBZ-BMvn2DwQpaLR0DY0JhtA1DNaTPiwteJW8OaIGJJPsRjwmPOdKRQpUUoB8WXO2KKfzKqnAvDNysQYAEmwRMtaDi8k9i6YL1lJPtSWWUPT87z-D3VAuY8Io29m1hpKDBLEkW-MnKrYAa4MMxaLZoeWmqcfAyNSzeAiv71-7LG_tnw4KpDvVjtDqCozXmwUw8G7_M2JXj047nqAARY1DRSs0M3a9NRg1wTxIrrfRDm3s51fC6KGE0Xl8DZXcl8N5t6za-2b8m1X437AnuRc-5POHLzTyg_OPEBLNPwt8IVVFoj2WfyS6vRTg8x1tVm0iKSRtcpxO-wUfnA5Bi7HALoTkWhLrzf8KyWIk_Dn5JpX3ZaNs9sWOXFTPJWfbAa5N2ZM0Esaf4jBxgt047zDgrVTnzxKTQLcsN8mkdYye33XDQVcpUEWPzeNXn3v3oHPGkFmTEkkYp_IDusI7idepf-eS7dWhvY7bnzYOIbXJlmd9TqM9PHGgBHjjZyBR7JOzD5mrQ4mvQWTQPa4tI2_N3i1o9rvS1JNr3xQ6p9tLHEDOzH7xBB5K7GK0eeUh3MO3wVvQk974bYl9yQ4e3hY2Pe_H4Hbg9ifk5TdqzJOnYrZMMF6h_EKdBmUSrdxt3A9Uxz4Jt31B6Ui32uLzdWgIkedsEVF2_5wYql_yk2jbr9MH26cLqyKh_ZbOqzdkQj-Air5urLRt17BHD_dBEVZgGdRvMHd8wYjxhAW5OTkRmIzZZ9qQDIZjFARBfW0dcprL5Eplf8yMFH6cQOjlXoct3HyjnYYTrzbPio3qLt5cyVTGGaMNpOvOdeBKRe2B3NwKEfNrp4AwDmemIz29R7u65hYBIJMpLBcMK3DIuitCU_Eu2-7sLy6FHnqnEIq531SoaJQKemTF7wYlcqIYglzJSB4bXb8fWzS9n8Q7D3Zf9r18lXK_2MiWf4XguIkMisKRkX7zixOF5kiBu2Bf4I1CBug4tuZFSKrvmQHRgkSE-dh7gIeIGWNgUrW9iKF6r2Cuja9xkCcMt4Cie_gebqAMDCLTJPhMgYDzLoIOU3cfD6xzvraL7IF2G2D6vLT9D7_QeqaodtjeqaKOResVIjMqZNfsc6an6gtMRxA7relsenQOfLqQmNe5lPcfjcHa30fplHcw2U05G5Hu7EAZw8vsZvNiKnqIpeq4fSUF7cf-0nfQBxHDbkqf_KCRnG_dVDZPZ0lEShmGDetTdbgd4QK8SpC26YAxDP-gVasLeAb7nVXQPV7CP8jEV5lqIDyCelE0LaaG5nFJoaO_DQ0chNQcQ11QyzDdcvd9FT7PSVNW7u0tgkIp1hasDq5zlfVzZo9A6Rq1VLGpHupzqBJ3La9laElYIquKkGYLcOIJ7k2OSIjY1nnDOdGN4xF6ZVQyD4nG27rb6tY_8JYy0pTf7F9U7Zo9qpwntV_yKt5p9lZlWFvG8RPzytugooEiYuFfOc9ch-enRV7F0Ovhvk15D21_RnbwbYj0a4E6mf3S8cFZ9_dvr1OWLPAxtg-CsheTx86fiib9C7aIHwbYo3qsDKI5rh1qtrjG1wX6LPyCDxpUVkUeNjW58mvkSNVbMu5vLpLjCiMcX2FPxyaJ05YQ-D6utglHA56hu4CwNlXLO2Fz-hSZ418lzCMLDedXIVm9Pdvqg0xXCXePjLZSbJST_BKr452lQZFxyFTPVByF-FKMgsQnX6vChUaejqVW76jIsYUk2MsQZjIn4wtD8HRcRARWi8io5BtEgvrG3l_kX0yVSZI67RcZYo9pz57pJMAUrg-JmPiHa2QRLKJW9GNll0ip7rbKL8EM0xSPZ5bUBAuF2McHWHbR4q7J6Qsnqp8tLc3IEj3DnqWPLGAX_W0Ja2z9rXQRskGp40Gng5dWGtBbks8N2DKRhIrR9fwkW-YY4MZlLvn_Row3V_OBVgP10hxFTX1JAQmwPceeWD4t8X7FAFgzPeID7LjaLrhKL2VUULAKD23KfAQMDHgKgYerz_Q41GJkwCm_S4qaKerQXzVL2NL0ddjGuFwDbjspUdlFFUA5dIvMWHvlCYLtrQ07-PrieNthnAy96ArDNLobiRmHqiapBFGxw1Pj_NE3Ywzv1oLpkTJMkbLXwQbMh4UhC3ILQ99YdVvsk_p24aj1xV1HWsgV8Pwvz91v6SKM0YUA58eEwpJgGxxBdimk97nYzdEgpCtrLbyc6SlWM62emmooOC0hsEdjJVKl8un1N0sBJLun5rz8QCKaSb0DRQHw2iBDchhN7I7idmezmSTQiiZP97-r46Sl6moyEqP4WSMvIq8pcWPBy2XPSDkakVeBJe6-fmRW9_INURBtvi-cIcorS7Qn4ENm79KHq9opAslX9StNuBVBmE0LrK2lngxCp7vJNNVUzB-zyPNYJ5hTbcYYU4IPYYRHQTLVtDdG_fTKMiwE95RmYZ7VU8rjQzbDDFUF8L3fkfJkVvPV8f0NWQj22fxvRtT-akmXTjzc6nENHjCCfoQUd1Mpj6KuL4ZbLLKnXkPZYouz_F_OZpiUA4ONZUuC_PbxqgTHIIT0rWqgvhPWeovZw0gwBMUiPjAL5Ajb89p5g7IhTYUfkMadkBEmbqsIL5bWDP_lKG_ryQho1XF8O_NKIMBKbY3GqcdJjyowlxGuEfpPjQExbZhs4ZPLer_IeEjSf7xrFCGRfnHIOimhLqa1TmCg8c2B_QnTMBXdF8dC398EZ5zZhAYOpI1ZuO18uPbXNHHoudcFzBvtFw1q5JnxoDGJXf_VJoGThrudbpoo99IcIIvJ9D55euOTqencfi9JHbCIKpmGez15HCrPZVB2qyMOTF0XLcyubxwO600fOZ0zA1Q3ecjtsyqCX3bUmySFzBH4tr7zqoGFE5ljDjZb3mlnMZFBxNvoU2XrxPH1rWtceEkIURuLflSW4VBm0AkEEecr1Wf-NoK6l9hlSqEGTlAquYV0sCNsTAiqeNxTsxjELQsXSO3T9uDbEgDVWJCPYVBkGWCqtOExQhH1dCTO90iVxmm-2edlnSVoDZEHqQeBWEkUzPUovNEdMrROBpVxnJsr3ThkpLVuUI1_nvrO4JDKrfYPShF6d4qNwOAgdk8A7-94qRsXxm0A6UIfZGxZTEDgepqlh3qBpbcOrJ9DR44s8_FFtJPwf5o40Cop8t-9JZu8vwrfvPvOk_JDOTbG5TR6i-SasZdqri7_7iPvQqr_J11rxtUTng6jH3ROJje1Y8rS2HNVqn6LZy9gsIksYZuFQqQ8S47BNiPPS3lHyEcLOzD8F1ebmXTI3q3NJutD2tzUKq2EE5RSRoSePF9Lr4PESO5FO260H5DtYDTp8rBVt7ytg3K56u_aPR4Pglr84dQUEPxdHPg57SQ5J6L9w3vRfodmh0g.m2hrzfXcQgzimkfo5BFCABnRKxjjbs-I7J21biRZlH8\",\"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\":1776107253174},\"identity\":{\"subject\":\"199e77147bb845fbab9416cdaff59726\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IjFKVkI4VVdCTkRUV0UxMTRTUlhLNEhMT0NDTU1HWFRKTExWRDZLOVgiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEwODc1MywiaWF0IjoxNzc2MTA1NDUzLCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiMTk5ZTc3MTQ3YmI4NDVmYmFiOTQxNmNkYWZmNTk3MjYiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiIxYzYwMWQxNS1mOGVhLTQyNGItYThjYS04N2Q1NjQ1NTM4MGUiLCJhdF9oYXNoIjoiWThYRDNTdmNwVG9scE9xdEJDSGt1ZyJ9.JcGH0caOVVtFLv58y3lJ3Xfyi9iDCdzfsUdzIibUwRgqm9ZxTnYAq835ip_i1zyEPfOkF7ZV9PSJde8XEdzNwVjFQOgjggpzJ_7RJO5qcNwpc18sSV_IyqzPL55PBvWHuG6h-tlHWH_g__jR__QXVHRPDu3kafyFaFQGObmNQeOKHw6j_4UsYbfLKMYbJd46nQSvY9kjwRukjV77y0MoZ-_Xeryfu25dprjFIoywADBwVJCrf9HPBpSqTcjmA4TCaUN3DIwEgO0BPxOj-ezoPcHtPF03IOurJOVJJ97_bRzDhKvC9xc3j4ZyUg2xUjQFEygb1oR_ghlhDx84Lm177Q\"},\"dpopKeyThumbprint\":\"qAzmSWd2aHuVq5rviVF3HFPqmOzJQizm8RemOVX5wY8\",\"issuedAtEpochMs\":1776105453175,\"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\":1776105452000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjE0NDMyMiwiaWF0IjoxNzc2MTQyNTIyLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiYTc5ZjBkOTQtZmNkYy00NDZhLWJlNjMtYmRjYjkwNmY1YzlmIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxNDI1MjIsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.eH4t9ps1Ph06sY66OR0sC6bYuhXJXciPvojNFtTYNYicFTJT9m4edq_TtHCU4n9Yr-Vw6MyyD6AvX44wEIfgAC90zGa0BTjD4y6PywLaEo-rmZFs8-E1hdn4DCSbKHJB9aBYmXcp8OIHLy0MLzHuqa4Y3xCsXhKqGyYFeZj4uXaRWAEr74DlwI7XcdUlMajG49JdHv73kfnFG9HkqI3EnNBX5CfhLRq2sQhFvymlcGpLCKEkJX42qjTG5dvQQIWCudqCcNFStjMYzxWGs9c8VKbOFOlZrXwVpnlGcrCn2mD9ut4qnYuFpzX8qpaPrzZxCE9jIrw6-l6HbYek5r60zQ\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.PEszGEIQ3O136LT_vFDfo2CbMdTIk37DXzEm2VPoirfO-aKqxxCcDOdj0aaH0s6d9PwBgLPt_RZLn8rT-fpdSk0ICEhLRBJWmgcE0vZIfXFAwRyu7USfMUNgB1A48Mg5muxNRPj9eLyoytdNGw5aj_jRF4DFTLLIwOwttNxkBG1--X_AoQ5sl43Sxl7GzqtaoKuDgUiBxrWDh7fOLBzhQPAqSjAsxMWm1R4SVXVm7ehav-u6BL6nqdKJLNP-gZ9vW6fojuObAdZjXYV2VcK_PcJ1kca6gnk1E4f1iORrrDemxijY7ehlCOzA5uFjkg1aGE8uv8Fk5OKyCknQ960PTQ.HPrD2--P6CMnwhVPFTmUQw.QQfXBObkdBR2iyuDnMYkh61eoWQGknp_eXkGp0Qpk7CTZHY1ikZHfwAXNY1n_PcvJrRapQP4BPC9NQGlW6atcZgr4WKj3yHYFgFH7--Bf1mJLlLzG0boyoOeyTeVQheoTXxd7EXRqLyCa4KFTLfXBrNW7si2jo6B3njpwxDeMoIUmuSA6RK8DMwY5PheNNtNWhmjg2j6ResKz39FznAeBl85RriEDPIdF7RfpOK4xXYMbJiPtFt-LBuKkG8S5PFngFbvqc4b1jKMY5lCyDtJQIpIZQ_rfRlZZNv4vefgXoH0bdYTj2IhCe8dy1rkIRXW1K3PdRLOMiZmHFZHDAopPWz-5fV-IpEuW8LAmu7HQXcrJwh1VbBO4BkamS_aTx0anJlppWx8KW0A12YFLxC69oDsdDK1Avf_H1ab3WZRsuvSt1-LF9LmgOmhyJyLsTmr6yY7PRRZDdCci0-RieKC3U736lRLi8bxdnHJqBl3jZBVi_vLpEYWBPDRDA0sbkM9dhQ9AdM-Vy-iVtMmIJmUxvz9MzUFW8NSjlILIEoaleXOhk15zO-6hYDR9LP7D2CxgA8t2MuI9tCvR2n4NqrwMgKlf0DTjEM3VAjZJcbDapRPuDY_uWn6AHfU08QRktOjFploeFAtVi9n8KYJl8VCF_B_DxyQLBHrfhORGSlUMZwMKWQXmxAZAj9aD8D794oxpCJLXJoML-dxvLiOYHw5PnChUWQ7nTmCJMUEcSe_OUiBRTmpRN-E2Uzgglx-D9D3G7Lf0pv666kFarf8c4TSH8sU0MGkIpqyKb1nIhOos5ONAMd8XvDmRD_jNnNfedCmUo_ZIdZYv8RvsLOKEi6Z4ALP7aLZKDTmr6MnE91YYsjJc7DOjSZABzszMyg-BIg7aK78tfDfRI5TlheYwZ6F9-v1SMANrbAnI3aTCIxsogejt-k7TJvBx6B3eeCA3WEyb22KY7kfnB1aBP_m7EvW7rPtX0IE5w4_uWs476x_hMf6k8yg8ZnACONC-4Axklxtp1h15sgyUs-7B46WL0UMKVL-38HPNPmcPvpAouZL56bqCqY7QuhqZ5G0PUjCxj0lBAwfJmA7XPIjenauL2LNiqc_Gd787ZsRwZ8EYH5Y-QmTrf8Aq_jGTONk5M6IxJXSne80qN8h6B4pWWdLdeOGPvXfmXqJw5DMl5aPm99i75T0qQQYlok11BMUabXOv0Rno2JubvhhcqDkSBYn-Q4y2y3Gy1X5W-ODEYzz4Za50a8LXPgFxM3RdOlfLG9B1oAuKlSRTbh2lB_nIQBnOoD9eRtq_dTZangrkWSM1mbdkI4kRpObaWy0S0SzuikGa4AkEDaO67Ot3naLImuQGOEvpTVD3rrhROFKJx85nf-eux_hw4Evg7zzAPxOkZMZbyhXLu0qHRi4cbZ9yPtHiLV6P3EtTrm0GNuSqi1I20c_S7dbJkZbTWgMizvwWaaDor4lgmzybFAX4X0hMr6XnaHNu8xfNhJz7-aljVx8oDBzhVb_wgkoJGKPjNKwdQeousz6QUSD0qtSM0gr5bLCY6lrT5MKzqTf6keWNe8B8fELLBdZfNtQazHrFPzwfiLaDKElC_qUmns85e96N8xlUzqzQDSJc3TIgzpzHD9ASqPvl9FbdV_vflJgGUtE1jGK0tZZ7C3xhsEVhmGnwv6lZx4ZEoKZUtFUPg1GdQmC7oM-6ArvrBqLfTwQ3WAyuFUwK70x-cNmbh_-IDI6pCXJa3tJ1ubGWMr5_rm5PBBPWxXnliMu1Y5d66_nUtXY81iG_Hkoe06-Fy6wCJKWPmrWgrE3rwc2okKVS9AwaxpjX2YNB6Et34TrOlmISnFq6wcxhHYyHs9U2KaY1bIcUzwjhh3IIyKnlz5n-ZW8CJwMakpm2EJf-_rNgVKLf4cnfIiGQSoQBOwOf7QydU3g-AG66B9YBdnMxw_fMgT3PwlKiRztbWnNzvB1QL7EfSKQvaCh6CE9ZO_u1gVGTjpTAKpuoS53WSuPMwmGg-iBVBq8JZ0wEpNTATQxTU9tUk15ZYMBxiJ8srgdt_alV1Lvz07xk-FVYG8sPISe462mwLIwHuED_CN17ohodZfAkD4I_9W_u3fM5J1RB7TS-XXwwpmF1b2VeaNXGpAISu04fke8zlNWLVpbrBgGPP2riICy3C1uAR9WkyfteiW4G2QXbOqV10KzrCetADrkOxS4kz3h53rCn28AB5Q3qAYHFJGSfWy9ZHEvHFl2yAumS_7SOj4dTampKvHQg78IAkp1iCwmkzn11olr6WqZKl5nkjO9jXzYy61w1IoM7JhaS3ApZT2rQexVzVld684-8gvM9t7v0yba_t73Uh-tplItwoBNeZl-w9x48ieea4IOEiesZRwZsqtow2XgnRGPAGPIPxmXtmsEcY6vMfzlpA92xan2CMnHTQToNK83w8x3KbnGO_8fWmivQ3S4k_5gg-2AzgHiKzmF6WVVY3ewla5OGU4hUD9Qui6miD1fKBonupJMyMp8DoLAsRc992qi25WqyVXgdE11tZ_ZrCfCYdoEnP_hhL_1choHk8LIej20wW0yuF6hDewKCH2WvvxeB6rdKp_4hNhaZjktxsW3cf3tifXbvveKmH4hUUZanekr2CZE46iaXAXTDZtrCjYXWQeKkBcNQ63JoZvlI5aAOne0Se_3tYnQ2HfDC5slNt3AwiBEzj8ON7loQJG3znVtFv7m9vDj0lyBJtnYiJITGC4qfb1G3QcD1DhhTR-iDte1bO0eLjQh0Mlla37JF2OMfbM6iVlfJYo-vcyli-V1paV64xuNbCc47t9AAGQTNkDhzi48EtMtXqznAj1qA1m-TRAXi3JCu1R4wbvthBisBL6ER5Jubxf7BthSBpQAjL0XCH-KEQRVix68W9qk1pvuZK1g6bcx4CoWxSBCqijbX3Gd_bZ_kNiZOqms9ICZiyyhHohyqXWmCdKUfRpWmbIzxCPQScXIyXLP-orn_YLRy9gUgOW6togWduZn4XPLSbBHA2ajuANtuV51D9znz9UXVLFGb3iH9KmJUooFGfbDWvSdK3dp6eXWBgenijYXQjLPNLQ5SlOfzKnV3IY7aISV7NfGUIVyqiK_Nv_UV6bCHjlxy6UIWtdmOUocw7n7oPGiJjBQMEODlFT2tKUMI8YbLQnH4h7a8ZekaUuX5dYm2V8vWOvKX9GRo3rpaMNXuz6bMZTHJRNqiqccFH0hbguWC-P8rgQrV-7zurD9U_7X2NSDdo0VNvQ0fwL8hu04lEbVOyfZ7cfwiHHzmQrBjodtlhoMmiE53RaCvJSJJWfyCKFRvJ_T8HbCUx33cn8oEEUcpqjT0S5SgkTpBORDDEh0lOuR1x5TFpkTxJxgOzK4zvATNvN9UIx6dwQwYTkQRPzKShSttuh7LP-VmEBYRke88QnpUuP6bDPNcrPgFRwgQBFXCqs6Bc0IwtMSk3C3OyU75iLBs7PhhuLrU2p3HztSWV2zsqCaJZNddiuOa0R8cOjZGWv_p7CAJNBk-nhS206v5j79jC-ha2pJFTHZKalhGC8QGvcNS7eHgecP7kn0SCzSNshBXbgzn-TzOXJtSXASxhSFJd2ATePQ152p6p9tm-ZodtDCdXSmb5w2GjVMQxMRgtFxZpgWj2LSQL2lAhpOT86KidmN-rpUcsBsdd2DqgQEn6DfzY1W_nmCdLLrZPKg8E64rlB6y5D1SPbRXTh-RqFXHJ9Avf2EOt9jZ_gyfVa6gMvlxE2Hcf5UWYRk9549FbZBvq_BOhU5EI0pYkSdfVj25GIeSXWODF47dNei5wPrTfinrlwf4NffB_ax_aARxCxV4VrESI-3E9gxq1gC2oHcXMuLDuY_L79-5G5biF-aReWE6SDnd9J7CZB1djg5dUWt7k3QC9L2C8o7HOpugBDxKpkIhn_es94BnBXyfrYLDso6rnDkX6L9RG-DK82LJn-Gk04SN4hsS-wQVs4YaosNOl2HeUug786Pym26UEraRikDYPBesoqJAIUQX-pLwqwVvuF4DFXXUvb1pmDRr3UpMJypuQunyKQX9av5wEVGax4ZCpyD6ifzkMO1Ev8PiDDTtiwR_8Q7POP71hvXIx2kuxW9dla8YzTu992LTwKJhYQE4S7YgCow6hOUNIVj52Ml2M5BWTkhUi3_ZhzmGSXJzLkCnpA0A2H338rYf7BjAzezqoiz0i8D3dGJunt5v0GFe_vvm2VnacMT5lZq5iIzI-UZuEjlRTTVtBNb2WgC_wwe9nE7C8XMUoTy0VB8yqO9joZ_wZOtSHKq5IScX5xbLzB1eJo8SAVt49bB3GpCa30bLzySkpKW1q55q46l8brri8snNgg5cj9ff9oZt-cdO0jouBkoPsMsbM73NlWLrJ5604yh6JwwJ2GkV8JLtjsX8MyDcwTXnbLyHpn5qUz-1Jn2zFzEB_Uy3r4ZWATKgi4pHO86BVtTsBRTmiXZ7Ko5wniY2dFKYLfAmcXm5JQ9XxxysSef9KZluU8JJIddLPEWby1vhPiO5_KbBaHI6XAnKQ7WkBzuW-9JHM-q9nCpXvtNc06Rq7rZzgHQ6U8mwRtuW5pgLOXB3nVv4l4jLBjHFEhdDilaEocjDXVMbk1VcDWAY-bpeNYKCMHc0k5Qk7lB-0qQTmP9nOe3s4-lbW4a6HIEuzIgXdr2uHMe7NDTJTUelOaQrIELvx7ts2CivEHY62RilyJIxQ8xrHjTMeqSW1s6gUvA7RxStSy_RuwDqzKHGFvtcQ.mo021ygVM3nxRlGDOjKtDWSc7S2PasCZB_y68OQ3H6c\",\"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\":1776144321964},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjE0NTgyMiwiaWF0IjoxNzc2MTQyNTIyLCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiI3ZWE1MzlmNS0yNmIwLTRhMjYtYjRkNy03MDlkYTUyMmVkNTUiLCJhdF9oYXNoIjoianZQVXNOWV82bzZRc3VQQXNLWWE5dyJ9.qArsS6sQ9qY0DTnZwMma1kL6f3DEeq6R_El3uqObn7tdQGW5TPS_yl1w5V6gKzsrE-x7TgRBhNtpt3p_K5lPK0WsQe-wF-twHeFwhJazQFLs0mMU2tN49WMlJVeqaIfWimS-k7iSf1VJPoGTDZ1E0o6CJ5DhCXXIYS1MW8AQBoLksxPuhGlnnU7IXFFJraxHxOs-rxNjbaz46ovHzrntYt52lCNGcAy4d4WRGUtYCRQqvF2HGT65IxD_IuG5KZPYcQVnaVIR1GWk6Be7PB1LaawLMQ6FupVkS_lE0O4acrjSnZOiDbIDwelRVo6r66LxeOXl7ZUqsiOe-WhJBRO9ww\"},\"dpopKeyThumbprint\":\"4FG7mBznUAW3pOk1L26XbjuZnf9L_l4KMeYMOzHaSdU\",\"issuedAtEpochMs\":1776142522964,\"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\":1776142522000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" ], [ "stellaops.helper.preferences", @@ -28,7 +28,7 @@ ], [ "stellaops.auth.session.info", - "{\"subject\":\"199e77147bb845fbab9416cdaff59726\",\"expiresAtEpochMs\":1776107253174,\"issuedAtEpochMs\":1776105453175,\"dpopKeyThumbprint\":\"qAzmSWd2aHuVq5rviVF3HFPqmOzJQizm8RemOVX5wY8\",\"tenantId\":\"demo-prod\"}" + "{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"expiresAtEpochMs\":1776144321964,\"issuedAtEpochMs\":1776142522964,\"dpopKeyThumbprint\":\"4FG7mBznUAW3pOk1L26XbjuZnf9L_l4KMeYMOzHaSdU\",\"tenantId\":\"demo-prod\"}" ], [ "stellaops.sidebar.preferences", @@ -38,7 +38,7 @@ "sessionStorageEntries": [ [ "stellaops.auth.session.full", - "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IjFKVkI4VVdCTkRUV0UxMTRTUlhLNEhMT0NDTU1HWFRKTExWRDZLOVgiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEwNzI1MywiaWF0IjoxNzc2MTA1NDUzLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiZTRiNGYyMzAtMjdmYy00OGM0LTllMmMtMTk0NTU4MmRiMWMyIiwic3ViIjoiMTk5ZTc3MTQ3YmI4NDVmYmFiOTQxNmNkYWZmNTk3MjYiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMDU0NTIsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.0pgGOI_zwY_SADTfCnH-VcYXfndryb_htp67MIiW0AG4zLMkGHoEkNs8HXIMxwhPN4LAP_kfpmiQn1zgJZA5nFcBfnzUlbOaIUqUWFpVuv8P-JQKd63LZ_q8LnAWnYsEKgIphpqCYHTOYgcOUkuxrAKkUyyXC3rpuIK48zVhzHpwDDTHPBRxq_ZIXOHhZJ0YvtxqwV-Kc1AO_ZD4D0fstTV2ffllBdbNsIqjuhumP6w2Ga168MJ2jAsmorJ4iGVj-aLkkDCI3wcS6Mb8NBtNmJv4alB0CGOv_159kZBVkhCYejtTSOEWgTfkmDozMRWg9JdGqtgEt73_cbU19L_WGg\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiJUWUtCWUlITVpFVFpYWlk3WllFQ1A0OVMyQ0ZKVElPVkIwWlFEX0tHIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.lAQkETzitD88nXcC-kfreQdLmDJKGuEZhALU_Vvt3WFHFjfkfvv08Kx55nCTQ63QXUcBkiLNZRY_0piiJ2_gPyb0U07ohwZfgRJHL_IjnvIXRY8_DvAVi_X1R8tUCixkSrpOcrlM7hNv9Z_pNKPRBsVGIPHQ2QemzJ8JrVgjVEUKMoB9IYAvf2JXkHefPWi-qZk-jo_apMABnFamd6WpZsA6WiKPPvzqc8X-cdJ9zQ5_GB5BKyp7PUzmxCAk5qUC9dKuBhUGP-RIVKbY7p2IZ1zfwRvhz0UlVZxl_wv2scwcc36rMeCz5fYRYZPdS3UWme8a1q9m3VxSOGUw82dOJQ.2OkN0F40NVGK46DCMv0ajg.da5uTUoxgxoYRONkKBd8Xz89h9zDQBqwWRHS62QkzhFHmI-p6WbTfIW3_3pGaJKxIi9EBVNZpSDF-YjV3AaCl28WwVDmuUkPWhLFW5826zJKb9p1l7IEr3DqHvY_zu2Z_W1c1wWUSU9KCVvNCGvzE_MzNaqUh1Se9-YPV2PKGjOBxp1tp7JUIlIAZB9oL0Kwat3z6Qhhaoci8t_cwrPi0CwlXJiKg0yCYYFtK84c7rWZkf4abhT5R33fHFy0R75z2r77tRNMhhHM6dqkcBYVzufw6rxxkUR26_lf4JrDagIhP3aqhjrUprPH8MOGN7PHqxEyxSfEqCB_l4S_grVcyYfFgMbO6H8gek0DA8W_d2zbXOiUbgLL7CbSfxyzs_wTGdLBiu18B3qapqkjRH_AkI4-ILitqh-n153p6KsBV4iJmyHo-if641tcHXoHtG0TJ1852wFa676WiAt1xCv6hdHsacTJZTrzojynmPkwlJrBdf_NydcJNPMICZNt5PXXgkaQu68fhw25XToaQcSKeeRhR2LWBLcZ_VYG3XtGPDAdSxKQEAy25KS-Obrn_SgkcOWrhb2RPHNNDxPfjmUOQDVS2S-Q3Q68NrMOspgjSQbVosnfiQImNSIF5CqjAHE4JXLpZuc0twsfplt0y9_RPtw8wkxR2H2eiNTsIRTo0vmXJMSWexNF_PA_SHhEMM9F_l7x2PHrWAVUBiEfdilakRQbF4eU0IzMSWLy_4ifHvcw4jRX1TkUch-c5ieuPQtnKP8H7HFI_Y1Wj6sTdKrys7S--2m84v0JYjMkUaNc3XiWr2jDE0J-j_TA17VlGnmF2qBkkNy9PEAvricM-emv4mejH0vA7NffKbN41lHflVeCppeXTWKJze-kJvQjJJoSL2OsVJFiscyyo0MfQAcIurtJ7wtWAzk0E10rYlvwXp0HHKMosaE7r_hcGjv-sSd6lscfk59fuGiSrzD5zJvwJRQdzhrsI8HFkRyUFtEkNoeROlrwzdj6IgDgz6T6vp7tuFPSkv4cEGQ1kfx3RUH0u7LVxZFA6Jev_22szOlS2RJ8rwT7Wnua9z96Qk58MYoq8r_mpBVGEr34hUIK9xJI5U8CclbJJlYmoeo9XsMEUz6gUG2ojDoUjYa8V-r1H-zXY8KA9_yAYjmGVQ9NsJZqidbZL_K07qi3C1yZ0RLMvVa2S15hXtYwFM0ZGKLcDkPqjCy6v9DFoKv2h-4fZL8HjYTfsFJYhWHgxSyL3-4Q7b0ZXRc_bdixGtAWhekKPtnKzrDohF2-2R3xFf8M2C1VUrRe8xcLdElZ2DpkYHrrzhZznVfP9kNskDRkwm1izCW5ICglVc75UQEQPF9AW39DED-vrqXBZ-BMvn2DwQpaLR0DY0JhtA1DNaTPiwteJW8OaIGJJPsRjwmPOdKRQpUUoB8WXO2KKfzKqnAvDNysQYAEmwRMtaDi8k9i6YL1lJPtSWWUPT87z-D3VAuY8Io29m1hpKDBLEkW-MnKrYAa4MMxaLZoeWmqcfAyNSzeAiv71-7LG_tnw4KpDvVjtDqCozXmwUw8G7_M2JXj047nqAARY1DRSs0M3a9NRg1wTxIrrfRDm3s51fC6KGE0Xl8DZXcl8N5t6za-2b8m1X437AnuRc-5POHLzTyg_OPEBLNPwt8IVVFoj2WfyS6vRTg8x1tVm0iKSRtcpxO-wUfnA5Bi7HALoTkWhLrzf8KyWIk_Dn5JpX3ZaNs9sWOXFTPJWfbAa5N2ZM0Esaf4jBxgt047zDgrVTnzxKTQLcsN8mkdYye33XDQVcpUEWPzeNXn3v3oHPGkFmTEkkYp_IDusI7idepf-eS7dWhvY7bnzYOIbXJlmd9TqM9PHGgBHjjZyBR7JOzD5mrQ4mvQWTQPa4tI2_N3i1o9rvS1JNr3xQ6p9tLHEDOzH7xBB5K7GK0eeUh3MO3wVvQk974bYl9yQ4e3hY2Pe_H4Hbg9ifk5TdqzJOnYrZMMF6h_EKdBmUSrdxt3A9Uxz4Jt31B6Ui32uLzdWgIkedsEVF2_5wYql_yk2jbr9MH26cLqyKh_ZbOqzdkQj-Air5urLRt17BHD_dBEVZgGdRvMHd8wYjxhAW5OTkRmIzZZ9qQDIZjFARBfW0dcprL5Eplf8yMFH6cQOjlXoct3HyjnYYTrzbPio3qLt5cyVTGGaMNpOvOdeBKRe2B3NwKEfNrp4AwDmemIz29R7u65hYBIJMpLBcMK3DIuitCU_Eu2-7sLy6FHnqnEIq531SoaJQKemTF7wYlcqIYglzJSB4bXb8fWzS9n8Q7D3Zf9r18lXK_2MiWf4XguIkMisKRkX7zixOF5kiBu2Bf4I1CBug4tuZFSKrvmQHRgkSE-dh7gIeIGWNgUrW9iKF6r2Cuja9xkCcMt4Cie_gebqAMDCLTJPhMgYDzLoIOU3cfD6xzvraL7IF2G2D6vLT9D7_QeqaodtjeqaKOResVIjMqZNfsc6an6gtMRxA7relsenQOfLqQmNe5lPcfjcHa30fplHcw2U05G5Hu7EAZw8vsZvNiKnqIpeq4fSUF7cf-0nfQBxHDbkqf_KCRnG_dVDZPZ0lEShmGDetTdbgd4QK8SpC26YAxDP-gVasLeAb7nVXQPV7CP8jEV5lqIDyCelE0LaaG5nFJoaO_DQ0chNQcQ11QyzDdcvd9FT7PSVNW7u0tgkIp1hasDq5zlfVzZo9A6Rq1VLGpHupzqBJ3La9laElYIquKkGYLcOIJ7k2OSIjY1nnDOdGN4xF6ZVQyD4nG27rb6tY_8JYy0pTf7F9U7Zo9qpwntV_yKt5p9lZlWFvG8RPzytugooEiYuFfOc9ch-enRV7F0Ovhvk15D21_RnbwbYj0a4E6mf3S8cFZ9_dvr1OWLPAxtg-CsheTx86fiib9C7aIHwbYo3qsDKI5rh1qtrjG1wX6LPyCDxpUVkUeNjW58mvkSNVbMu5vLpLjCiMcX2FPxyaJ05YQ-D6utglHA56hu4CwNlXLO2Fz-hSZ418lzCMLDedXIVm9Pdvqg0xXCXePjLZSbJST_BKr452lQZFxyFTPVByF-FKMgsQnX6vChUaejqVW76jIsYUk2MsQZjIn4wtD8HRcRARWi8io5BtEgvrG3l_kX0yVSZI67RcZYo9pz57pJMAUrg-JmPiHa2QRLKJW9GNll0ip7rbKL8EM0xSPZ5bUBAuF2McHWHbR4q7J6Qsnqp8tLc3IEj3DnqWPLGAX_W0Ja2z9rXQRskGp40Gng5dWGtBbks8N2DKRhIrR9fwkW-YY4MZlLvn_Row3V_OBVgP10hxFTX1JAQmwPceeWD4t8X7FAFgzPeID7LjaLrhKL2VUULAKD23KfAQMDHgKgYerz_Q41GJkwCm_S4qaKerQXzVL2NL0ddjGuFwDbjspUdlFFUA5dIvMWHvlCYLtrQ07-PrieNthnAy96ArDNLobiRmHqiapBFGxw1Pj_NE3Ywzv1oLpkTJMkbLXwQbMh4UhC3ILQ99YdVvsk_p24aj1xV1HWsgV8Pwvz91v6SKM0YUA58eEwpJgGxxBdimk97nYzdEgpCtrLbyc6SlWM62emmooOC0hsEdjJVKl8un1N0sBJLun5rz8QCKaSb0DRQHw2iBDchhN7I7idmezmSTQiiZP97-r46Sl6moyEqP4WSMvIq8pcWPBy2XPSDkakVeBJe6-fmRW9_INURBtvi-cIcorS7Qn4ENm79KHq9opAslX9StNuBVBmE0LrK2lngxCp7vJNNVUzB-zyPNYJ5hTbcYYU4IPYYRHQTLVtDdG_fTKMiwE95RmYZ7VU8rjQzbDDFUF8L3fkfJkVvPV8f0NWQj22fxvRtT-akmXTjzc6nENHjCCfoQUd1Mpj6KuL4ZbLLKnXkPZYouz_F_OZpiUA4ONZUuC_PbxqgTHIIT0rWqgvhPWeovZw0gwBMUiPjAL5Ajb89p5g7IhTYUfkMadkBEmbqsIL5bWDP_lKG_ryQho1XF8O_NKIMBKbY3GqcdJjyowlxGuEfpPjQExbZhs4ZPLer_IeEjSf7xrFCGRfnHIOimhLqa1TmCg8c2B_QnTMBXdF8dC398EZ5zZhAYOpI1ZuO18uPbXNHHoudcFzBvtFw1q5JnxoDGJXf_VJoGThrudbpoo99IcIIvJ9D55euOTqencfi9JHbCIKpmGez15HCrPZVB2qyMOTF0XLcyubxwO600fOZ0zA1Q3ecjtsyqCX3bUmySFzBH4tr7zqoGFE5ljDjZb3mlnMZFBxNvoU2XrxPH1rWtceEkIURuLflSW4VBm0AkEEecr1Wf-NoK6l9hlSqEGTlAquYV0sCNsTAiqeNxTsxjELQsXSO3T9uDbEgDVWJCPYVBkGWCqtOExQhH1dCTO90iVxmm-2edlnSVoDZEHqQeBWEkUzPUovNEdMrROBpVxnJsr3ThkpLVuUI1_nvrO4JDKrfYPShF6d4qNwOAgdk8A7-94qRsXxm0A6UIfZGxZTEDgepqlh3qBpbcOrJ9DR44s8_FFtJPwf5o40Cop8t-9JZu8vwrfvPvOk_JDOTbG5TR6i-SasZdqri7_7iPvQqr_J11rxtUTng6jH3ROJje1Y8rS2HNVqn6LZy9gsIksYZuFQqQ8S47BNiPPS3lHyEcLOzD8F1ebmXTI3q3NJutD2tzUKq2EE5RSRoSePF9Lr4PESO5FO260H5DtYDTp8rBVt7ytg3K56u_aPR4Pglr84dQUEPxdHPg57SQ5J6L9w3vRfodmh0g.m2hrzfXcQgzimkfo5BFCABnRKxjjbs-I7J21biRZlH8\",\"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\":1776107253174},\"identity\":{\"subject\":\"199e77147bb845fbab9416cdaff59726\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IjFKVkI4VVdCTkRUV0UxMTRTUlhLNEhMT0NDTU1HWFRKTExWRDZLOVgiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEwODc1MywiaWF0IjoxNzc2MTA1NDUzLCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiMTk5ZTc3MTQ3YmI4NDVmYmFiOTQxNmNkYWZmNTk3MjYiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiIxYzYwMWQxNS1mOGVhLTQyNGItYThjYS04N2Q1NjQ1NTM4MGUiLCJhdF9oYXNoIjoiWThYRDNTdmNwVG9scE9xdEJDSGt1ZyJ9.JcGH0caOVVtFLv58y3lJ3Xfyi9iDCdzfsUdzIibUwRgqm9ZxTnYAq835ip_i1zyEPfOkF7ZV9PSJde8XEdzNwVjFQOgjggpzJ_7RJO5qcNwpc18sSV_IyqzPL55PBvWHuG6h-tlHWH_g__jR__QXVHRPDu3kafyFaFQGObmNQeOKHw6j_4UsYbfLKMYbJd46nQSvY9kjwRukjV77y0MoZ-_Xeryfu25dprjFIoywADBwVJCrf9HPBpSqTcjmA4TCaUN3DIwEgO0BPxOj-ezoPcHtPF03IOurJOVJJ97_bRzDhKvC9xc3j4ZyUg2xUjQFEygb1oR_ghlhDx84Lm177Q\"},\"dpopKeyThumbprint\":\"qAzmSWd2aHuVq5rviVF3HFPqmOzJQizm8RemOVX5wY8\",\"issuedAtEpochMs\":1776105453175,\"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\":1776105452000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjE0NDMyMiwiaWF0IjoxNzc2MTQyNTIyLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiYTc5ZjBkOTQtZmNkYy00NDZhLWJlNjMtYmRjYjkwNmY1YzlmIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxNDI1MjIsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.eH4t9ps1Ph06sY66OR0sC6bYuhXJXciPvojNFtTYNYicFTJT9m4edq_TtHCU4n9Yr-Vw6MyyD6AvX44wEIfgAC90zGa0BTjD4y6PywLaEo-rmZFs8-E1hdn4DCSbKHJB9aBYmXcp8OIHLy0MLzHuqa4Y3xCsXhKqGyYFeZj4uXaRWAEr74DlwI7XcdUlMajG49JdHv73kfnFG9HkqI3EnNBX5CfhLRq2sQhFvymlcGpLCKEkJX42qjTG5dvQQIWCudqCcNFStjMYzxWGs9c8VKbOFOlZrXwVpnlGcrCn2mD9ut4qnYuFpzX8qpaPrzZxCE9jIrw6-l6HbYek5r60zQ\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.PEszGEIQ3O136LT_vFDfo2CbMdTIk37DXzEm2VPoirfO-aKqxxCcDOdj0aaH0s6d9PwBgLPt_RZLn8rT-fpdSk0ICEhLRBJWmgcE0vZIfXFAwRyu7USfMUNgB1A48Mg5muxNRPj9eLyoytdNGw5aj_jRF4DFTLLIwOwttNxkBG1--X_AoQ5sl43Sxl7GzqtaoKuDgUiBxrWDh7fOLBzhQPAqSjAsxMWm1R4SVXVm7ehav-u6BL6nqdKJLNP-gZ9vW6fojuObAdZjXYV2VcK_PcJ1kca6gnk1E4f1iORrrDemxijY7ehlCOzA5uFjkg1aGE8uv8Fk5OKyCknQ960PTQ.HPrD2--P6CMnwhVPFTmUQw.QQfXBObkdBR2iyuDnMYkh61eoWQGknp_eXkGp0Qpk7CTZHY1ikZHfwAXNY1n_PcvJrRapQP4BPC9NQGlW6atcZgr4WKj3yHYFgFH7--Bf1mJLlLzG0boyoOeyTeVQheoTXxd7EXRqLyCa4KFTLfXBrNW7si2jo6B3njpwxDeMoIUmuSA6RK8DMwY5PheNNtNWhmjg2j6ResKz39FznAeBl85RriEDPIdF7RfpOK4xXYMbJiPtFt-LBuKkG8S5PFngFbvqc4b1jKMY5lCyDtJQIpIZQ_rfRlZZNv4vefgXoH0bdYTj2IhCe8dy1rkIRXW1K3PdRLOMiZmHFZHDAopPWz-5fV-IpEuW8LAmu7HQXcrJwh1VbBO4BkamS_aTx0anJlppWx8KW0A12YFLxC69oDsdDK1Avf_H1ab3WZRsuvSt1-LF9LmgOmhyJyLsTmr6yY7PRRZDdCci0-RieKC3U736lRLi8bxdnHJqBl3jZBVi_vLpEYWBPDRDA0sbkM9dhQ9AdM-Vy-iVtMmIJmUxvz9MzUFW8NSjlILIEoaleXOhk15zO-6hYDR9LP7D2CxgA8t2MuI9tCvR2n4NqrwMgKlf0DTjEM3VAjZJcbDapRPuDY_uWn6AHfU08QRktOjFploeFAtVi9n8KYJl8VCF_B_DxyQLBHrfhORGSlUMZwMKWQXmxAZAj9aD8D794oxpCJLXJoML-dxvLiOYHw5PnChUWQ7nTmCJMUEcSe_OUiBRTmpRN-E2Uzgglx-D9D3G7Lf0pv666kFarf8c4TSH8sU0MGkIpqyKb1nIhOos5ONAMd8XvDmRD_jNnNfedCmUo_ZIdZYv8RvsLOKEi6Z4ALP7aLZKDTmr6MnE91YYsjJc7DOjSZABzszMyg-BIg7aK78tfDfRI5TlheYwZ6F9-v1SMANrbAnI3aTCIxsogejt-k7TJvBx6B3eeCA3WEyb22KY7kfnB1aBP_m7EvW7rPtX0IE5w4_uWs476x_hMf6k8yg8ZnACONC-4Axklxtp1h15sgyUs-7B46WL0UMKVL-38HPNPmcPvpAouZL56bqCqY7QuhqZ5G0PUjCxj0lBAwfJmA7XPIjenauL2LNiqc_Gd787ZsRwZ8EYH5Y-QmTrf8Aq_jGTONk5M6IxJXSne80qN8h6B4pWWdLdeOGPvXfmXqJw5DMl5aPm99i75T0qQQYlok11BMUabXOv0Rno2JubvhhcqDkSBYn-Q4y2y3Gy1X5W-ODEYzz4Za50a8LXPgFxM3RdOlfLG9B1oAuKlSRTbh2lB_nIQBnOoD9eRtq_dTZangrkWSM1mbdkI4kRpObaWy0S0SzuikGa4AkEDaO67Ot3naLImuQGOEvpTVD3rrhROFKJx85nf-eux_hw4Evg7zzAPxOkZMZbyhXLu0qHRi4cbZ9yPtHiLV6P3EtTrm0GNuSqi1I20c_S7dbJkZbTWgMizvwWaaDor4lgmzybFAX4X0hMr6XnaHNu8xfNhJz7-aljVx8oDBzhVb_wgkoJGKPjNKwdQeousz6QUSD0qtSM0gr5bLCY6lrT5MKzqTf6keWNe8B8fELLBdZfNtQazHrFPzwfiLaDKElC_qUmns85e96N8xlUzqzQDSJc3TIgzpzHD9ASqPvl9FbdV_vflJgGUtE1jGK0tZZ7C3xhsEVhmGnwv6lZx4ZEoKZUtFUPg1GdQmC7oM-6ArvrBqLfTwQ3WAyuFUwK70x-cNmbh_-IDI6pCXJa3tJ1ubGWMr5_rm5PBBPWxXnliMu1Y5d66_nUtXY81iG_Hkoe06-Fy6wCJKWPmrWgrE3rwc2okKVS9AwaxpjX2YNB6Et34TrOlmISnFq6wcxhHYyHs9U2KaY1bIcUzwjhh3IIyKnlz5n-ZW8CJwMakpm2EJf-_rNgVKLf4cnfIiGQSoQBOwOf7QydU3g-AG66B9YBdnMxw_fMgT3PwlKiRztbWnNzvB1QL7EfSKQvaCh6CE9ZO_u1gVGTjpTAKpuoS53WSuPMwmGg-iBVBq8JZ0wEpNTATQxTU9tUk15ZYMBxiJ8srgdt_alV1Lvz07xk-FVYG8sPISe462mwLIwHuED_CN17ohodZfAkD4I_9W_u3fM5J1RB7TS-XXwwpmF1b2VeaNXGpAISu04fke8zlNWLVpbrBgGPP2riICy3C1uAR9WkyfteiW4G2QXbOqV10KzrCetADrkOxS4kz3h53rCn28AB5Q3qAYHFJGSfWy9ZHEvHFl2yAumS_7SOj4dTampKvHQg78IAkp1iCwmkzn11olr6WqZKl5nkjO9jXzYy61w1IoM7JhaS3ApZT2rQexVzVld684-8gvM9t7v0yba_t73Uh-tplItwoBNeZl-w9x48ieea4IOEiesZRwZsqtow2XgnRGPAGPIPxmXtmsEcY6vMfzlpA92xan2CMnHTQToNK83w8x3KbnGO_8fWmivQ3S4k_5gg-2AzgHiKzmF6WVVY3ewla5OGU4hUD9Qui6miD1fKBonupJMyMp8DoLAsRc992qi25WqyVXgdE11tZ_ZrCfCYdoEnP_hhL_1choHk8LIej20wW0yuF6hDewKCH2WvvxeB6rdKp_4hNhaZjktxsW3cf3tifXbvveKmH4hUUZanekr2CZE46iaXAXTDZtrCjYXWQeKkBcNQ63JoZvlI5aAOne0Se_3tYnQ2HfDC5slNt3AwiBEzj8ON7loQJG3znVtFv7m9vDj0lyBJtnYiJITGC4qfb1G3QcD1DhhTR-iDte1bO0eLjQh0Mlla37JF2OMfbM6iVlfJYo-vcyli-V1paV64xuNbCc47t9AAGQTNkDhzi48EtMtXqznAj1qA1m-TRAXi3JCu1R4wbvthBisBL6ER5Jubxf7BthSBpQAjL0XCH-KEQRVix68W9qk1pvuZK1g6bcx4CoWxSBCqijbX3Gd_bZ_kNiZOqms9ICZiyyhHohyqXWmCdKUfRpWmbIzxCPQScXIyXLP-orn_YLRy9gUgOW6togWduZn4XPLSbBHA2ajuANtuV51D9znz9UXVLFGb3iH9KmJUooFGfbDWvSdK3dp6eXWBgenijYXQjLPNLQ5SlOfzKnV3IY7aISV7NfGUIVyqiK_Nv_UV6bCHjlxy6UIWtdmOUocw7n7oPGiJjBQMEODlFT2tKUMI8YbLQnH4h7a8ZekaUuX5dYm2V8vWOvKX9GRo3rpaMNXuz6bMZTHJRNqiqccFH0hbguWC-P8rgQrV-7zurD9U_7X2NSDdo0VNvQ0fwL8hu04lEbVOyfZ7cfwiHHzmQrBjodtlhoMmiE53RaCvJSJJWfyCKFRvJ_T8HbCUx33cn8oEEUcpqjT0S5SgkTpBORDDEh0lOuR1x5TFpkTxJxgOzK4zvATNvN9UIx6dwQwYTkQRPzKShSttuh7LP-VmEBYRke88QnpUuP6bDPNcrPgFRwgQBFXCqs6Bc0IwtMSk3C3OyU75iLBs7PhhuLrU2p3HztSWV2zsqCaJZNddiuOa0R8cOjZGWv_p7CAJNBk-nhS206v5j79jC-ha2pJFTHZKalhGC8QGvcNS7eHgecP7kn0SCzSNshBXbgzn-TzOXJtSXASxhSFJd2ATePQ152p6p9tm-ZodtDCdXSmb5w2GjVMQxMRgtFxZpgWj2LSQL2lAhpOT86KidmN-rpUcsBsdd2DqgQEn6DfzY1W_nmCdLLrZPKg8E64rlB6y5D1SPbRXTh-RqFXHJ9Avf2EOt9jZ_gyfVa6gMvlxE2Hcf5UWYRk9549FbZBvq_BOhU5EI0pYkSdfVj25GIeSXWODF47dNei5wPrTfinrlwf4NffB_ax_aARxCxV4VrESI-3E9gxq1gC2oHcXMuLDuY_L79-5G5biF-aReWE6SDnd9J7CZB1djg5dUWt7k3QC9L2C8o7HOpugBDxKpkIhn_es94BnBXyfrYLDso6rnDkX6L9RG-DK82LJn-Gk04SN4hsS-wQVs4YaosNOl2HeUug786Pym26UEraRikDYPBesoqJAIUQX-pLwqwVvuF4DFXXUvb1pmDRr3UpMJypuQunyKQX9av5wEVGax4ZCpyD6ifzkMO1Ev8PiDDTtiwR_8Q7POP71hvXIx2kuxW9dla8YzTu992LTwKJhYQE4S7YgCow6hOUNIVj52Ml2M5BWTkhUi3_ZhzmGSXJzLkCnpA0A2H338rYf7BjAzezqoiz0i8D3dGJunt5v0GFe_vvm2VnacMT5lZq5iIzI-UZuEjlRTTVtBNb2WgC_wwe9nE7C8XMUoTy0VB8yqO9joZ_wZOtSHKq5IScX5xbLzB1eJo8SAVt49bB3GpCa30bLzySkpKW1q55q46l8brri8snNgg5cj9ff9oZt-cdO0jouBkoPsMsbM73NlWLrJ5604yh6JwwJ2GkV8JLtjsX8MyDcwTXnbLyHpn5qUz-1Jn2zFzEB_Uy3r4ZWATKgi4pHO86BVtTsBRTmiXZ7Ko5wniY2dFKYLfAmcXm5JQ9XxxysSef9KZluU8JJIddLPEWby1vhPiO5_KbBaHI6XAnKQ7WkBzuW-9JHM-q9nCpXvtNc06Rq7rZzgHQ6U8mwRtuW5pgLOXB3nVv4l4jLBjHFEhdDilaEocjDXVMbk1VcDWAY-bpeNYKCMHc0k5Qk7lB-0qQTmP9nOe3s4-lbW4a6HIEuzIgXdr2uHMe7NDTJTUelOaQrIELvx7ts2CivEHY62RilyJIxQ8xrHjTMeqSW1s6gUvA7RxStSy_RuwDqzKHGFvtcQ.mo021ygVM3nxRlGDOjKtDWSc7S2PasCZB_y68OQ3H6c\",\"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\":1776144321964},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjE0NTgyMiwiaWF0IjoxNzc2MTQyNTIyLCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiI3ZWE1MzlmNS0yNmIwLTRhMjYtYjRkNy03MDlkYTUyMmVkNTUiLCJhdF9oYXNoIjoianZQVXNOWV82bzZRc3VQQXNLWWE5dyJ9.qArsS6sQ9qY0DTnZwMma1kL6f3DEeq6R_El3uqObn7tdQGW5TPS_yl1w5V6gKzsrE-x7TgRBhNtpt3p_K5lPK0WsQe-wF-twHeFwhJazQFLs0mMU2tN49WMlJVeqaIfWimS-k7iSf1VJPoGTDZ1E0o6CJ5DhCXXIYS1MW8AQBoLksxPuhGlnnU7IXFFJraxHxOs-rxNjbaz46ovHzrntYt52lCNGcAy4d4WRGUtYCRQqvF2HGT65IxD_IuG5KZPYcQVnaVIR1GWk6Be7PB1LaawLMQ6FupVkS_lE0O4acrjSnZOiDbIDwelRVo6r66LxeOXl7ZUqsiOe-WhJBRO9ww\"},\"dpopKeyThumbprint\":\"4FG7mBznUAW3pOk1L26XbjuZnf9L_l4KMeYMOzHaSdU\",\"issuedAtEpochMs\":1776142522964,\"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\":1776142522000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" ], [ "stellaops:wasEverAuth", @@ -47,32 +47,9 @@ ] }, "events": { - "consoleErrors": [ - "Failed to load resource: the server responded with a status of 404 ()", - "Failed to load resource: the server responded with a status of 404 ()", - "Failed to load resource: the server responded with a status of 503 ()" - ], + "consoleErrors": [], "requestFailures": [], - "responseErrors": [ - { - "status": 404, - "method": "GET", - "url": "https://stella-ops.local/api/v1/doctor/scheduler/trends/categories/security?from=2025-04-18T18:37:33.202Z&to=2026-04-13T18:37:33.202Z", - "page": "https://stella-ops.local/" - }, - { - "status": 404, - "method": "GET", - "url": "https://stella-ops.local/api/v1/doctor/scheduler/trends/categories/platform?from=2025-04-18T18:37:33.202Z&to=2026-04-13T18:37:33.202Z", - "page": "https://stella-ops.local/" - }, - { - "status": 503, - "method": "GET", - "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", - "page": "https://stella-ops.local/" - } - ] + "responseErrors": [] }, "statePath": "C:\\dev\\New folder\\git.stella-ops.org\\src\\Web\\StellaOps.Web\\output\\playwright\\live-frontdoor-auth-state.json" } 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 789d845b3..5009e5a33 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 @@ -6,7 +6,7 @@ "localStorage": [ { "name": "stellaops.auth.session.full", - "value": "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IjFKVkI4VVdCTkRUV0UxMTRTUlhLNEhMT0NDTU1HWFRKTExWRDZLOVgiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEwNzI1MywiaWF0IjoxNzc2MTA1NDUzLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiZTRiNGYyMzAtMjdmYy00OGM0LTllMmMtMTk0NTU4MmRiMWMyIiwic3ViIjoiMTk5ZTc3MTQ3YmI4NDVmYmFiOTQxNmNkYWZmNTk3MjYiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMDU0NTIsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.0pgGOI_zwY_SADTfCnH-VcYXfndryb_htp67MIiW0AG4zLMkGHoEkNs8HXIMxwhPN4LAP_kfpmiQn1zgJZA5nFcBfnzUlbOaIUqUWFpVuv8P-JQKd63LZ_q8LnAWnYsEKgIphpqCYHTOYgcOUkuxrAKkUyyXC3rpuIK48zVhzHpwDDTHPBRxq_ZIXOHhZJ0YvtxqwV-Kc1AO_ZD4D0fstTV2ffllBdbNsIqjuhumP6w2Ga168MJ2jAsmorJ4iGVj-aLkkDCI3wcS6Mb8NBtNmJv4alB0CGOv_159kZBVkhCYejtTSOEWgTfkmDozMRWg9JdGqtgEt73_cbU19L_WGg\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiJUWUtCWUlITVpFVFpYWlk3WllFQ1A0OVMyQ0ZKVElPVkIwWlFEX0tHIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.lAQkETzitD88nXcC-kfreQdLmDJKGuEZhALU_Vvt3WFHFjfkfvv08Kx55nCTQ63QXUcBkiLNZRY_0piiJ2_gPyb0U07ohwZfgRJHL_IjnvIXRY8_DvAVi_X1R8tUCixkSrpOcrlM7hNv9Z_pNKPRBsVGIPHQ2QemzJ8JrVgjVEUKMoB9IYAvf2JXkHefPWi-qZk-jo_apMABnFamd6WpZsA6WiKPPvzqc8X-cdJ9zQ5_GB5BKyp7PUzmxCAk5qUC9dKuBhUGP-RIVKbY7p2IZ1zfwRvhz0UlVZxl_wv2scwcc36rMeCz5fYRYZPdS3UWme8a1q9m3VxSOGUw82dOJQ.2OkN0F40NVGK46DCMv0ajg.da5uTUoxgxoYRONkKBd8Xz89h9zDQBqwWRHS62QkzhFHmI-p6WbTfIW3_3pGaJKxIi9EBVNZpSDF-YjV3AaCl28WwVDmuUkPWhLFW5826zJKb9p1l7IEr3DqHvY_zu2Z_W1c1wWUSU9KCVvNCGvzE_MzNaqUh1Se9-YPV2PKGjOBxp1tp7JUIlIAZB9oL0Kwat3z6Qhhaoci8t_cwrPi0CwlXJiKg0yCYYFtK84c7rWZkf4abhT5R33fHFy0R75z2r77tRNMhhHM6dqkcBYVzufw6rxxkUR26_lf4JrDagIhP3aqhjrUprPH8MOGN7PHqxEyxSfEqCB_l4S_grVcyYfFgMbO6H8gek0DA8W_d2zbXOiUbgLL7CbSfxyzs_wTGdLBiu18B3qapqkjRH_AkI4-ILitqh-n153p6KsBV4iJmyHo-if641tcHXoHtG0TJ1852wFa676WiAt1xCv6hdHsacTJZTrzojynmPkwlJrBdf_NydcJNPMICZNt5PXXgkaQu68fhw25XToaQcSKeeRhR2LWBLcZ_VYG3XtGPDAdSxKQEAy25KS-Obrn_SgkcOWrhb2RPHNNDxPfjmUOQDVS2S-Q3Q68NrMOspgjSQbVosnfiQImNSIF5CqjAHE4JXLpZuc0twsfplt0y9_RPtw8wkxR2H2eiNTsIRTo0vmXJMSWexNF_PA_SHhEMM9F_l7x2PHrWAVUBiEfdilakRQbF4eU0IzMSWLy_4ifHvcw4jRX1TkUch-c5ieuPQtnKP8H7HFI_Y1Wj6sTdKrys7S--2m84v0JYjMkUaNc3XiWr2jDE0J-j_TA17VlGnmF2qBkkNy9PEAvricM-emv4mejH0vA7NffKbN41lHflVeCppeXTWKJze-kJvQjJJoSL2OsVJFiscyyo0MfQAcIurtJ7wtWAzk0E10rYlvwXp0HHKMosaE7r_hcGjv-sSd6lscfk59fuGiSrzD5zJvwJRQdzhrsI8HFkRyUFtEkNoeROlrwzdj6IgDgz6T6vp7tuFPSkv4cEGQ1kfx3RUH0u7LVxZFA6Jev_22szOlS2RJ8rwT7Wnua9z96Qk58MYoq8r_mpBVGEr34hUIK9xJI5U8CclbJJlYmoeo9XsMEUz6gUG2ojDoUjYa8V-r1H-zXY8KA9_yAYjmGVQ9NsJZqidbZL_K07qi3C1yZ0RLMvVa2S15hXtYwFM0ZGKLcDkPqjCy6v9DFoKv2h-4fZL8HjYTfsFJYhWHgxSyL3-4Q7b0ZXRc_bdixGtAWhekKPtnKzrDohF2-2R3xFf8M2C1VUrRe8xcLdElZ2DpkYHrrzhZznVfP9kNskDRkwm1izCW5ICglVc75UQEQPF9AW39DED-vrqXBZ-BMvn2DwQpaLR0DY0JhtA1DNaTPiwteJW8OaIGJJPsRjwmPOdKRQpUUoB8WXO2KKfzKqnAvDNysQYAEmwRMtaDi8k9i6YL1lJPtSWWUPT87z-D3VAuY8Io29m1hpKDBLEkW-MnKrYAa4MMxaLZoeWmqcfAyNSzeAiv71-7LG_tnw4KpDvVjtDqCozXmwUw8G7_M2JXj047nqAARY1DRSs0M3a9NRg1wTxIrrfRDm3s51fC6KGE0Xl8DZXcl8N5t6za-2b8m1X437AnuRc-5POHLzTyg_OPEBLNPwt8IVVFoj2WfyS6vRTg8x1tVm0iKSRtcpxO-wUfnA5Bi7HALoTkWhLrzf8KyWIk_Dn5JpX3ZaNs9sWOXFTPJWfbAa5N2ZM0Esaf4jBxgt047zDgrVTnzxKTQLcsN8mkdYye33XDQVcpUEWPzeNXn3v3oHPGkFmTEkkYp_IDusI7idepf-eS7dWhvY7bnzYOIbXJlmd9TqM9PHGgBHjjZyBR7JOzD5mrQ4mvQWTQPa4tI2_N3i1o9rvS1JNr3xQ6p9tLHEDOzH7xBB5K7GK0eeUh3MO3wVvQk974bYl9yQ4e3hY2Pe_H4Hbg9ifk5TdqzJOnYrZMMF6h_EKdBmUSrdxt3A9Uxz4Jt31B6Ui32uLzdWgIkedsEVF2_5wYql_yk2jbr9MH26cLqyKh_ZbOqzdkQj-Air5urLRt17BHD_dBEVZgGdRvMHd8wYjxhAW5OTkRmIzZZ9qQDIZjFARBfW0dcprL5Eplf8yMFH6cQOjlXoct3HyjnYYTrzbPio3qLt5cyVTGGaMNpOvOdeBKRe2B3NwKEfNrp4AwDmemIz29R7u65hYBIJMpLBcMK3DIuitCU_Eu2-7sLy6FHnqnEIq531SoaJQKemTF7wYlcqIYglzJSB4bXb8fWzS9n8Q7D3Zf9r18lXK_2MiWf4XguIkMisKRkX7zixOF5kiBu2Bf4I1CBug4tuZFSKrvmQHRgkSE-dh7gIeIGWNgUrW9iKF6r2Cuja9xkCcMt4Cie_gebqAMDCLTJPhMgYDzLoIOU3cfD6xzvraL7IF2G2D6vLT9D7_QeqaodtjeqaKOResVIjMqZNfsc6an6gtMRxA7relsenQOfLqQmNe5lPcfjcHa30fplHcw2U05G5Hu7EAZw8vsZvNiKnqIpeq4fSUF7cf-0nfQBxHDbkqf_KCRnG_dVDZPZ0lEShmGDetTdbgd4QK8SpC26YAxDP-gVasLeAb7nVXQPV7CP8jEV5lqIDyCelE0LaaG5nFJoaO_DQ0chNQcQ11QyzDdcvd9FT7PSVNW7u0tgkIp1hasDq5zlfVzZo9A6Rq1VLGpHupzqBJ3La9laElYIquKkGYLcOIJ7k2OSIjY1nnDOdGN4xF6ZVQyD4nG27rb6tY_8JYy0pTf7F9U7Zo9qpwntV_yKt5p9lZlWFvG8RPzytugooEiYuFfOc9ch-enRV7F0Ovhvk15D21_RnbwbYj0a4E6mf3S8cFZ9_dvr1OWLPAxtg-CsheTx86fiib9C7aIHwbYo3qsDKI5rh1qtrjG1wX6LPyCDxpUVkUeNjW58mvkSNVbMu5vLpLjCiMcX2FPxyaJ05YQ-D6utglHA56hu4CwNlXLO2Fz-hSZ418lzCMLDedXIVm9Pdvqg0xXCXePjLZSbJST_BKr452lQZFxyFTPVByF-FKMgsQnX6vChUaejqVW76jIsYUk2MsQZjIn4wtD8HRcRARWi8io5BtEgvrG3l_kX0yVSZI67RcZYo9pz57pJMAUrg-JmPiHa2QRLKJW9GNll0ip7rbKL8EM0xSPZ5bUBAuF2McHWHbR4q7J6Qsnqp8tLc3IEj3DnqWPLGAX_W0Ja2z9rXQRskGp40Gng5dWGtBbks8N2DKRhIrR9fwkW-YY4MZlLvn_Row3V_OBVgP10hxFTX1JAQmwPceeWD4t8X7FAFgzPeID7LjaLrhKL2VUULAKD23KfAQMDHgKgYerz_Q41GJkwCm_S4qaKerQXzVL2NL0ddjGuFwDbjspUdlFFUA5dIvMWHvlCYLtrQ07-PrieNthnAy96ArDNLobiRmHqiapBFGxw1Pj_NE3Ywzv1oLpkTJMkbLXwQbMh4UhC3ILQ99YdVvsk_p24aj1xV1HWsgV8Pwvz91v6SKM0YUA58eEwpJgGxxBdimk97nYzdEgpCtrLbyc6SlWM62emmooOC0hsEdjJVKl8un1N0sBJLun5rz8QCKaSb0DRQHw2iBDchhN7I7idmezmSTQiiZP97-r46Sl6moyEqP4WSMvIq8pcWPBy2XPSDkakVeBJe6-fmRW9_INURBtvi-cIcorS7Qn4ENm79KHq9opAslX9StNuBVBmE0LrK2lngxCp7vJNNVUzB-zyPNYJ5hTbcYYU4IPYYRHQTLVtDdG_fTKMiwE95RmYZ7VU8rjQzbDDFUF8L3fkfJkVvPV8f0NWQj22fxvRtT-akmXTjzc6nENHjCCfoQUd1Mpj6KuL4ZbLLKnXkPZYouz_F_OZpiUA4ONZUuC_PbxqgTHIIT0rWqgvhPWeovZw0gwBMUiPjAL5Ajb89p5g7IhTYUfkMadkBEmbqsIL5bWDP_lKG_ryQho1XF8O_NKIMBKbY3GqcdJjyowlxGuEfpPjQExbZhs4ZPLer_IeEjSf7xrFCGRfnHIOimhLqa1TmCg8c2B_QnTMBXdF8dC398EZ5zZhAYOpI1ZuO18uPbXNHHoudcFzBvtFw1q5JnxoDGJXf_VJoGThrudbpoo99IcIIvJ9D55euOTqencfi9JHbCIKpmGez15HCrPZVB2qyMOTF0XLcyubxwO600fOZ0zA1Q3ecjtsyqCX3bUmySFzBH4tr7zqoGFE5ljDjZb3mlnMZFBxNvoU2XrxPH1rWtceEkIURuLflSW4VBm0AkEEecr1Wf-NoK6l9hlSqEGTlAquYV0sCNsTAiqeNxTsxjELQsXSO3T9uDbEgDVWJCPYVBkGWCqtOExQhH1dCTO90iVxmm-2edlnSVoDZEHqQeBWEkUzPUovNEdMrROBpVxnJsr3ThkpLVuUI1_nvrO4JDKrfYPShF6d4qNwOAgdk8A7-94qRsXxm0A6UIfZGxZTEDgepqlh3qBpbcOrJ9DR44s8_FFtJPwf5o40Cop8t-9JZu8vwrfvPvOk_JDOTbG5TR6i-SasZdqri7_7iPvQqr_J11rxtUTng6jH3ROJje1Y8rS2HNVqn6LZy9gsIksYZuFQqQ8S47BNiPPS3lHyEcLOzD8F1ebmXTI3q3NJutD2tzUKq2EE5RSRoSePF9Lr4PESO5FO260H5DtYDTp8rBVt7ytg3K56u_aPR4Pglr84dQUEPxdHPg57SQ5J6L9w3vRfodmh0g.m2hrzfXcQgzimkfo5BFCABnRKxjjbs-I7J21biRZlH8\",\"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\":1776107253174},\"identity\":{\"subject\":\"199e77147bb845fbab9416cdaff59726\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IjFKVkI4VVdCTkRUV0UxMTRTUlhLNEhMT0NDTU1HWFRKTExWRDZLOVgiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEwODc1MywiaWF0IjoxNzc2MTA1NDUzLCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiMTk5ZTc3MTQ3YmI4NDVmYmFiOTQxNmNkYWZmNTk3MjYiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiIxYzYwMWQxNS1mOGVhLTQyNGItYThjYS04N2Q1NjQ1NTM4MGUiLCJhdF9oYXNoIjoiWThYRDNTdmNwVG9scE9xdEJDSGt1ZyJ9.JcGH0caOVVtFLv58y3lJ3Xfyi9iDCdzfsUdzIibUwRgqm9ZxTnYAq835ip_i1zyEPfOkF7ZV9PSJde8XEdzNwVjFQOgjggpzJ_7RJO5qcNwpc18sSV_IyqzPL55PBvWHuG6h-tlHWH_g__jR__QXVHRPDu3kafyFaFQGObmNQeOKHw6j_4UsYbfLKMYbJd46nQSvY9kjwRukjV77y0MoZ-_Xeryfu25dprjFIoywADBwVJCrf9HPBpSqTcjmA4TCaUN3DIwEgO0BPxOj-ezoPcHtPF03IOurJOVJJ97_bRzDhKvC9xc3j4ZyUg2xUjQFEygb1oR_ghlhDx84Lm177Q\"},\"dpopKeyThumbprint\":\"qAzmSWd2aHuVq5rviVF3HFPqmOzJQizm8RemOVX5wY8\",\"issuedAtEpochMs\":1776105453175,\"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\":1776105452000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" + "value": "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjE0NDMyMiwiaWF0IjoxNzc2MTQyNTIyLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiYTc5ZjBkOTQtZmNkYy00NDZhLWJlNjMtYmRjYjkwNmY1YzlmIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxNDI1MjIsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.eH4t9ps1Ph06sY66OR0sC6bYuhXJXciPvojNFtTYNYicFTJT9m4edq_TtHCU4n9Yr-Vw6MyyD6AvX44wEIfgAC90zGa0BTjD4y6PywLaEo-rmZFs8-E1hdn4DCSbKHJB9aBYmXcp8OIHLy0MLzHuqa4Y3xCsXhKqGyYFeZj4uXaRWAEr74DlwI7XcdUlMajG49JdHv73kfnFG9HkqI3EnNBX5CfhLRq2sQhFvymlcGpLCKEkJX42qjTG5dvQQIWCudqCcNFStjMYzxWGs9c8VKbOFOlZrXwVpnlGcrCn2mD9ut4qnYuFpzX8qpaPrzZxCE9jIrw6-l6HbYek5r60zQ\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.PEszGEIQ3O136LT_vFDfo2CbMdTIk37DXzEm2VPoirfO-aKqxxCcDOdj0aaH0s6d9PwBgLPt_RZLn8rT-fpdSk0ICEhLRBJWmgcE0vZIfXFAwRyu7USfMUNgB1A48Mg5muxNRPj9eLyoytdNGw5aj_jRF4DFTLLIwOwttNxkBG1--X_AoQ5sl43Sxl7GzqtaoKuDgUiBxrWDh7fOLBzhQPAqSjAsxMWm1R4SVXVm7ehav-u6BL6nqdKJLNP-gZ9vW6fojuObAdZjXYV2VcK_PcJ1kca6gnk1E4f1iORrrDemxijY7ehlCOzA5uFjkg1aGE8uv8Fk5OKyCknQ960PTQ.HPrD2--P6CMnwhVPFTmUQw.QQfXBObkdBR2iyuDnMYkh61eoWQGknp_eXkGp0Qpk7CTZHY1ikZHfwAXNY1n_PcvJrRapQP4BPC9NQGlW6atcZgr4WKj3yHYFgFH7--Bf1mJLlLzG0boyoOeyTeVQheoTXxd7EXRqLyCa4KFTLfXBrNW7si2jo6B3njpwxDeMoIUmuSA6RK8DMwY5PheNNtNWhmjg2j6ResKz39FznAeBl85RriEDPIdF7RfpOK4xXYMbJiPtFt-LBuKkG8S5PFngFbvqc4b1jKMY5lCyDtJQIpIZQ_rfRlZZNv4vefgXoH0bdYTj2IhCe8dy1rkIRXW1K3PdRLOMiZmHFZHDAopPWz-5fV-IpEuW8LAmu7HQXcrJwh1VbBO4BkamS_aTx0anJlppWx8KW0A12YFLxC69oDsdDK1Avf_H1ab3WZRsuvSt1-LF9LmgOmhyJyLsTmr6yY7PRRZDdCci0-RieKC3U736lRLi8bxdnHJqBl3jZBVi_vLpEYWBPDRDA0sbkM9dhQ9AdM-Vy-iVtMmIJmUxvz9MzUFW8NSjlILIEoaleXOhk15zO-6hYDR9LP7D2CxgA8t2MuI9tCvR2n4NqrwMgKlf0DTjEM3VAjZJcbDapRPuDY_uWn6AHfU08QRktOjFploeFAtVi9n8KYJl8VCF_B_DxyQLBHrfhORGSlUMZwMKWQXmxAZAj9aD8D794oxpCJLXJoML-dxvLiOYHw5PnChUWQ7nTmCJMUEcSe_OUiBRTmpRN-E2Uzgglx-D9D3G7Lf0pv666kFarf8c4TSH8sU0MGkIpqyKb1nIhOos5ONAMd8XvDmRD_jNnNfedCmUo_ZIdZYv8RvsLOKEi6Z4ALP7aLZKDTmr6MnE91YYsjJc7DOjSZABzszMyg-BIg7aK78tfDfRI5TlheYwZ6F9-v1SMANrbAnI3aTCIxsogejt-k7TJvBx6B3eeCA3WEyb22KY7kfnB1aBP_m7EvW7rPtX0IE5w4_uWs476x_hMf6k8yg8ZnACONC-4Axklxtp1h15sgyUs-7B46WL0UMKVL-38HPNPmcPvpAouZL56bqCqY7QuhqZ5G0PUjCxj0lBAwfJmA7XPIjenauL2LNiqc_Gd787ZsRwZ8EYH5Y-QmTrf8Aq_jGTONk5M6IxJXSne80qN8h6B4pWWdLdeOGPvXfmXqJw5DMl5aPm99i75T0qQQYlok11BMUabXOv0Rno2JubvhhcqDkSBYn-Q4y2y3Gy1X5W-ODEYzz4Za50a8LXPgFxM3RdOlfLG9B1oAuKlSRTbh2lB_nIQBnOoD9eRtq_dTZangrkWSM1mbdkI4kRpObaWy0S0SzuikGa4AkEDaO67Ot3naLImuQGOEvpTVD3rrhROFKJx85nf-eux_hw4Evg7zzAPxOkZMZbyhXLu0qHRi4cbZ9yPtHiLV6P3EtTrm0GNuSqi1I20c_S7dbJkZbTWgMizvwWaaDor4lgmzybFAX4X0hMr6XnaHNu8xfNhJz7-aljVx8oDBzhVb_wgkoJGKPjNKwdQeousz6QUSD0qtSM0gr5bLCY6lrT5MKzqTf6keWNe8B8fELLBdZfNtQazHrFPzwfiLaDKElC_qUmns85e96N8xlUzqzQDSJc3TIgzpzHD9ASqPvl9FbdV_vflJgGUtE1jGK0tZZ7C3xhsEVhmGnwv6lZx4ZEoKZUtFUPg1GdQmC7oM-6ArvrBqLfTwQ3WAyuFUwK70x-cNmbh_-IDI6pCXJa3tJ1ubGWMr5_rm5PBBPWxXnliMu1Y5d66_nUtXY81iG_Hkoe06-Fy6wCJKWPmrWgrE3rwc2okKVS9AwaxpjX2YNB6Et34TrOlmISnFq6wcxhHYyHs9U2KaY1bIcUzwjhh3IIyKnlz5n-ZW8CJwMakpm2EJf-_rNgVKLf4cnfIiGQSoQBOwOf7QydU3g-AG66B9YBdnMxw_fMgT3PwlKiRztbWnNzvB1QL7EfSKQvaCh6CE9ZO_u1gVGTjpTAKpuoS53WSuPMwmGg-iBVBq8JZ0wEpNTATQxTU9tUk15ZYMBxiJ8srgdt_alV1Lvz07xk-FVYG8sPISe462mwLIwHuED_CN17ohodZfAkD4I_9W_u3fM5J1RB7TS-XXwwpmF1b2VeaNXGpAISu04fke8zlNWLVpbrBgGPP2riICy3C1uAR9WkyfteiW4G2QXbOqV10KzrCetADrkOxS4kz3h53rCn28AB5Q3qAYHFJGSfWy9ZHEvHFl2yAumS_7SOj4dTampKvHQg78IAkp1iCwmkzn11olr6WqZKl5nkjO9jXzYy61w1IoM7JhaS3ApZT2rQexVzVld684-8gvM9t7v0yba_t73Uh-tplItwoBNeZl-w9x48ieea4IOEiesZRwZsqtow2XgnRGPAGPIPxmXtmsEcY6vMfzlpA92xan2CMnHTQToNK83w8x3KbnGO_8fWmivQ3S4k_5gg-2AzgHiKzmF6WVVY3ewla5OGU4hUD9Qui6miD1fKBonupJMyMp8DoLAsRc992qi25WqyVXgdE11tZ_ZrCfCYdoEnP_hhL_1choHk8LIej20wW0yuF6hDewKCH2WvvxeB6rdKp_4hNhaZjktxsW3cf3tifXbvveKmH4hUUZanekr2CZE46iaXAXTDZtrCjYXWQeKkBcNQ63JoZvlI5aAOne0Se_3tYnQ2HfDC5slNt3AwiBEzj8ON7loQJG3znVtFv7m9vDj0lyBJtnYiJITGC4qfb1G3QcD1DhhTR-iDte1bO0eLjQh0Mlla37JF2OMfbM6iVlfJYo-vcyli-V1paV64xuNbCc47t9AAGQTNkDhzi48EtMtXqznAj1qA1m-TRAXi3JCu1R4wbvthBisBL6ER5Jubxf7BthSBpQAjL0XCH-KEQRVix68W9qk1pvuZK1g6bcx4CoWxSBCqijbX3Gd_bZ_kNiZOqms9ICZiyyhHohyqXWmCdKUfRpWmbIzxCPQScXIyXLP-orn_YLRy9gUgOW6togWduZn4XPLSbBHA2ajuANtuV51D9znz9UXVLFGb3iH9KmJUooFGfbDWvSdK3dp6eXWBgenijYXQjLPNLQ5SlOfzKnV3IY7aISV7NfGUIVyqiK_Nv_UV6bCHjlxy6UIWtdmOUocw7n7oPGiJjBQMEODlFT2tKUMI8YbLQnH4h7a8ZekaUuX5dYm2V8vWOvKX9GRo3rpaMNXuz6bMZTHJRNqiqccFH0hbguWC-P8rgQrV-7zurD9U_7X2NSDdo0VNvQ0fwL8hu04lEbVOyfZ7cfwiHHzmQrBjodtlhoMmiE53RaCvJSJJWfyCKFRvJ_T8HbCUx33cn8oEEUcpqjT0S5SgkTpBORDDEh0lOuR1x5TFpkTxJxgOzK4zvATNvN9UIx6dwQwYTkQRPzKShSttuh7LP-VmEBYRke88QnpUuP6bDPNcrPgFRwgQBFXCqs6Bc0IwtMSk3C3OyU75iLBs7PhhuLrU2p3HztSWV2zsqCaJZNddiuOa0R8cOjZGWv_p7CAJNBk-nhS206v5j79jC-ha2pJFTHZKalhGC8QGvcNS7eHgecP7kn0SCzSNshBXbgzn-TzOXJtSXASxhSFJd2ATePQ152p6p9tm-ZodtDCdXSmb5w2GjVMQxMRgtFxZpgWj2LSQL2lAhpOT86KidmN-rpUcsBsdd2DqgQEn6DfzY1W_nmCdLLrZPKg8E64rlB6y5D1SPbRXTh-RqFXHJ9Avf2EOt9jZ_gyfVa6gMvlxE2Hcf5UWYRk9549FbZBvq_BOhU5EI0pYkSdfVj25GIeSXWODF47dNei5wPrTfinrlwf4NffB_ax_aARxCxV4VrESI-3E9gxq1gC2oHcXMuLDuY_L79-5G5biF-aReWE6SDnd9J7CZB1djg5dUWt7k3QC9L2C8o7HOpugBDxKpkIhn_es94BnBXyfrYLDso6rnDkX6L9RG-DK82LJn-Gk04SN4hsS-wQVs4YaosNOl2HeUug786Pym26UEraRikDYPBesoqJAIUQX-pLwqwVvuF4DFXXUvb1pmDRr3UpMJypuQunyKQX9av5wEVGax4ZCpyD6ifzkMO1Ev8PiDDTtiwR_8Q7POP71hvXIx2kuxW9dla8YzTu992LTwKJhYQE4S7YgCow6hOUNIVj52Ml2M5BWTkhUi3_ZhzmGSXJzLkCnpA0A2H338rYf7BjAzezqoiz0i8D3dGJunt5v0GFe_vvm2VnacMT5lZq5iIzI-UZuEjlRTTVtBNb2WgC_wwe9nE7C8XMUoTy0VB8yqO9joZ_wZOtSHKq5IScX5xbLzB1eJo8SAVt49bB3GpCa30bLzySkpKW1q55q46l8brri8snNgg5cj9ff9oZt-cdO0jouBkoPsMsbM73NlWLrJ5604yh6JwwJ2GkV8JLtjsX8MyDcwTXnbLyHpn5qUz-1Jn2zFzEB_Uy3r4ZWATKgi4pHO86BVtTsBRTmiXZ7Ko5wniY2dFKYLfAmcXm5JQ9XxxysSef9KZluU8JJIddLPEWby1vhPiO5_KbBaHI6XAnKQ7WkBzuW-9JHM-q9nCpXvtNc06Rq7rZzgHQ6U8mwRtuW5pgLOXB3nVv4l4jLBjHFEhdDilaEocjDXVMbk1VcDWAY-bpeNYKCMHc0k5Qk7lB-0qQTmP9nOe3s4-lbW4a6HIEuzIgXdr2uHMe7NDTJTUelOaQrIELvx7ts2CivEHY62RilyJIxQ8xrHjTMeqSW1s6gUvA7RxStSy_RuwDqzKHGFvtcQ.mo021ygVM3nxRlGDOjKtDWSc7S2PasCZB_y68OQ3H6c\",\"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\":1776144321964},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjE0NTgyMiwiaWF0IjoxNzc2MTQyNTIyLCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiI3ZWE1MzlmNS0yNmIwLTRhMjYtYjRkNy03MDlkYTUyMmVkNTUiLCJhdF9oYXNoIjoianZQVXNOWV82bzZRc3VQQXNLWWE5dyJ9.qArsS6sQ9qY0DTnZwMma1kL6f3DEeq6R_El3uqObn7tdQGW5TPS_yl1w5V6gKzsrE-x7TgRBhNtpt3p_K5lPK0WsQe-wF-twHeFwhJazQFLs0mMU2tN49WMlJVeqaIfWimS-k7iSf1VJPoGTDZ1E0o6CJ5DhCXXIYS1MW8AQBoLksxPuhGlnnU7IXFFJraxHxOs-rxNjbaz46ovHzrntYt52lCNGcAy4d4WRGUtYCRQqvF2HGT65IxD_IuG5KZPYcQVnaVIR1GWk6Be7PB1LaawLMQ6FupVkS_lE0O4acrjSnZOiDbIDwelRVo6r66LxeOXl7ZUqsiOe-WhJBRO9ww\"},\"dpopKeyThumbprint\":\"4FG7mBznUAW3pOk1L26XbjuZnf9L_l4KMeYMOzHaSdU\",\"issuedAtEpochMs\":1776142522964,\"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\":1776142522000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" }, { "name": "stellaops.helper.preferences", @@ -26,7 +26,7 @@ }, { "name": "stellaops.auth.session.info", - "value": "{\"subject\":\"199e77147bb845fbab9416cdaff59726\",\"expiresAtEpochMs\":1776107253174,\"issuedAtEpochMs\":1776105453175,\"dpopKeyThumbprint\":\"qAzmSWd2aHuVq5rviVF3HFPqmOzJQizm8RemOVX5wY8\",\"tenantId\":\"demo-prod\"}" + "value": "{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"expiresAtEpochMs\":1776144321964,\"issuedAtEpochMs\":1776142522964,\"dpopKeyThumbprint\":\"4FG7mBznUAW3pOk1L26XbjuZnf9L_l4KMeYMOzHaSdU\",\"tenantId\":\"demo-prod\"}" }, { "name": "stellaops.sidebar.preferences", diff --git a/src/Web/StellaOps.Web/output/playwright/live-integrations-ui-bootstrap.auth.json b/src/Web/StellaOps.Web/output/playwright/live-integrations-ui-bootstrap.auth.json new file mode 100644 index 000000000..0abefef1e --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-integrations-ui-bootstrap.auth.json @@ -0,0 +1,55 @@ +{ + "authenticatedAtUtc": "2026-04-13T23:21:33.058Z", + "baseUrl": "https://stella-ops.local", + "finalUrl": "https://stella-ops.local/?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Dashboard - StellaOps", + "cookies": [], + "storage": { + "localStorageEntries": [ + [ + "stellaops.auth.session.full", + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyNDI5MCwiaWF0IjoxNzc2MTIyNDkwLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiOTU2ZjljNGUtNGVmMi00ODU0LTg0NTEtNTNiM2UwZTllMzc5Iiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMjI0OTAsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.SjscyX0IrOxirujiUezIVujTNN107P4A1SILVke6kF8sQPS3XC_0u3tIQKkEQzcDdmolLot-iR408Wm2uMIFKhZK4717tw3svwa48KsWSUoiW-fNErDjlPyVGVtzLmykdJsooqwBusoLJe2PwsJj0J3kkpT8YVJMm_AW-OEZxNfvTz_EM-I2ZVF32ErW4waWswbO_5CaNHziDNXlEsyT7eIEYVGvVY2UAV_Dr_VEXd-vvrXlf6t2onvXBpRr5bqsQOctCnV7aPkZqgew9GDPdeOtqr17l-uPs6O8KKKv5vTrj_YLNlBeM9DjmqYA6i07IWoOAx-GOtmV2a9KGXkQ-w\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.PGUaV_kPUQLr-BlrvYwSwQ7VZl5V_kUg8Yb3Q0RWjxvOcGjGIykdQvOrrTnfWk_U0EG-WWKY8HIjY7zGLVkMB4NkfFGN9-m7_JIDbvd50SBnYLeXC95HZPf0t0eJ45Prv5cvRTyt63EzHtHs_ttbp6ZLBQhqd_rmyop_q1AlKlfS8zcB45ZAlnpMBmiMpuQfxsOs9SzNvsbKvUF4UBq9VChgps4bCv3RDzOOpZbvhNTtA53af9nwoavqoB6utLqF5N7aXAC12XBMs2a2NVmdRMP3W4T-sZ1ksdhhKORbQdspXqu-PBzTuJ4Lq-HjWVZtQdO4T91I3fQb8zNXIScH7A.vk3i21BvJsqJvGklE3WW9Q.txCN69BgfMIdy9ghjTFQDEkgtI4VfJpz3-0oNNcePB_BeJqaaJryF_eNYXhUvFIz7SfRbCbjFPhS6wD_29YephOxZ6I9TyjpuncbVNila0ohV3eTiAzx6ZgVnJZmEUja3UU_nFTrJLZws2LXJU91SmGkq5-tQv4iPJMrIKkVTtUUOKbGT8gtTzQaSPAoU0rLk7vfmDKIKGm9yO-TKcgXCxny2odkSn87bfENLIaLC5uYbtVxbJEY_2oT0_ytuMEurnKcsgjv1FaVFLg7t2I1LgNIlKVfvCfMh1Q4k7wtitQhy_DAzgoo522-j4RWRqhvRrjAxG-PCVXHAqZlMakL81XCLdX2oMLgr4Aba_9g-APvG-gVvjOcNQzUuVBw5ThD3ESJEXeS-w3V0cZm66hSMQ5SjWmXo1fbpGD8V8wYb5UlOZvo1ZLEV3f4ao2F0GLhAHD2cB-VwX-SatfBOPvPRBgvECGI9fBG9qGn3gQ_RK7rh-HhH9tEsW5uCaphZpjTCvUVgJmUMQztXbS6yCfmQqQa0AL3y9fWQbtn121xbbduHS8R_0z-fNMfkS3HlI8AG7IBkYXyohezkhGT6HlIfKzpFBWQKmNKioe6HA-h5XZMLVtGABrKJmUm3omhS1i3rAFOZ4H3TlLpjnv3aVjZONSA2KlJ6UnAIwo8x3j_T4WHtKfxD-e24K_5rhAkhYql6vXZAhaQxz9NZoubrxeQgr7pJRj9xJmd63fricLcWDV56cMwQXYgNiQZ_kz3-uUKdS6pGqKCvnj2XSalpTjGzmAVol5kbNCzN7RysJlJUgbPunKOvwEoAZ3Dc1KDp056a6Ufw9NSp43j8YDF0hOW6oMasciFXCZnkbmlHeeH0WZs2q1dAWNFPP5c_avAoZZmNfBTbDrOsI75IvfX5QV2BDozwv7lIe3kBVeVeytHPn8DJtZc07aEpjFsItD0y4eko3MGGHt7GSDABpsuO3SsKIYNyZKLlCL1a90TbTRtoq473bZFKkCzKuKEFPZzWahp4D1gi19tRGlybpoaR0RfOHRT9ejF9heWbqykC7WrB2VsqIYzxm5GecjKL9JMlzC4u7cX8jRDu1MJcux0hEc1Vltztj7aFklgxRwK-2lA65T_X1dtF3WDG1UzuU_B4IKzRTr4Il39W7bdKKlrshp8zgmmYxXEvHZTUmVBNUU9V9haEXfYT92vcHZtDD8NNoKa2-asNI7jBFLOFbyLXXsed8HC6lLl8CU6DzO27TntztthxNxhSv2yzH6-TMv5fNtt_fZlP7ID1RjpqwxUqn9K8mGP6kyKfg5MfbytCQi6dFJqNgQbequExareeCb4G2cyP2vOYnzSyQrTnRnDsHqXiyANZzJbJXdI0FoVKuLUU8AlmCsCFWr35LrUlf_SyQdmV6jp-BFUV9gv5N5y89oragfI6SH6gacHG_c77VHegfpJMV309_h_srsmARpcWrA_Y9daO_VJjGPe0qos652xW7hs2qn_orD2O4VdbNgdP_KmVla0PzeTcx7pGIUlAFmD_xSDc52AMDmwk3cX_n4RxdHzGvyAJasRUKR2lfqRKLV5JHkFOUkGR5xQPgfEep68-mhnHRaBw3kE0kzGdBni5lpT8tBa3IK7ShuWp81B09cPKEbsGxqB9LPoff4sXRBF3vZKjvkx1lfyYKARtY1A1FNj3iQNvi8gFI3gy9fzSttpz4X1khh0S_mR6ou6r-aksCCK5TGx3gt_n9tXFXNJZ79wtsTlYU8V5AesRrEs6qKGvo2usx8um2P7OqrC_iwMqgF2YtUZe-OrLV_J5d6RrVXQGN9D6YMDZsJ0Dxo--ff7BgglXVjCKChdzA1Fzg6sLOKnL5SEobrC8SFDLMStK23QM-71b4VB2jhLVAV4HdErT6QpH1QIUhtQZtnMDFgwNXC0hemBIxeQjFc6q18K9Hv_c2TjoJ4QipIQI_9tGSE-0-VP7FCIlHEe3ONK7mihvx1ACYiWzd84xj21Wxi0aS-bAmvz9qJykLr9ct-O2bnP6HDdkquweCgxQ_pHsUIAWE87KkTboXXTSvAcBb9Mr7NI8wLHbrSJ3LCUtFg_RyGdEFW3B4gp-NuC-YZfM8X9iUvkqal80Fxe8onqWAvWtVnyfLBCxECgdiZgLgOvODBLHJUiFK5qcE4KgK--XOj9qs_yiUkuXrw7P43rCu1WpmoxdnvULGlfDvZg3O-AiB1ncDuz1YqxjMnMRBl5P01lQur-6VHRMTav4cxpbXiKdc2nw_R1ix_R7q2mefmXlKKRa3MiZiZFrdeTtexclWIFKMzBl6YGl7fPJccCyqw7YBBOBVj1Az6-KkLYxlATgErBYcfq93TYLpgV5Q8-8nFjTmNddcfIWLj3D8jRoT0E4PlzbfUnDWJaxQlrzkUdoq_SIIvBmRLT3n439_xjn7aTlfGY8TtAb4Ev8NKsBwXRd1IzdS2f3EMS2NHazDYMjhITFg92IqyL9w88qlpV90EqvzmeDvpKnFPlYzeUf8fy0IHHiD-oeKOGpXNrnE8Uh-fYUWMHMVcIKQ7Ag5VqmdJGuz3StHzva-SXa46pPrcx9n9Eso9qd72Jx38bZoYWKz4kfB1wSinEl6JTzJTOPCzHxJFSKYhqlCvuMvIDtvyRrOVhaN8z-h1V4OLZN3og3TtK6Ln6I40AXZjByK1naRG9yK_lJlzOGXkTlj_4vkpqazdbiDQBawIGNNJi8T7ZrzF8rvfnGOrsdNn5V833H53hufWSSnuFMOyWwQlxDKaPEBz0DYt2wW8cCxARG5NGQdyUw744ic9bfMS5zaGrGYZk-znteQP8k0OSeDEg49lGhFpeipkCWJkhUFVxfu0nv6H06PwlP9RdxBEkYVS_1D-P7Xow4fj47C3o5Scpgw4eRsnXu0jvp3fPBYTtaeCYYpCeri4EqVeYF3bVK0x04A7_asi2CGRd7Bc-1CYgeJ-gdB8Rh58u5Q6rLHs5D6ZHlyrtZH2bu_rZxMSETXf4bJBBI8umOUdzBWIv2P_Ww_uUVyCppvMdNeGDt8IZKM9CkrYk_xDguUH7AN-bZFHNt82idPTDVaD6BMeOnoqsvLhY22p3dzOp-oTqpdXTdq31lWgxo3xC4UbOLdESz0G1vBuRVoYnbh0zw5RTQrQRWXmeTBu81qAbM_hxrbsGCAF0zBQmaJqAmuxsAGoGTs1etz9_0VG6qX-DBFlpgoHTP1VA_tXbJTO3r52cTyaheX4xfZ8f19hzGu56umAh0cIxzKvdJetskCn8vFmJBEGicqIJu5oxEe_p23GLFQd8HSdG2MbmPd8OBuSiEeDUvmVwfmbkfQkODNGheGL6a-d9C_b6a-6LXpFI8erjxs2ruDINAkmd15OLOjUHzY66aTSuPuGlDLRwBuycQAvwuIjQb7hTfwxjoZGXhc_IsMhpJoj5zAOzYTE7gf_Dg-u1pmpXd0x6ySWv4Ms1yC-voilS8sdCoVNEmudKAJXY1cd29X2ILAQ09fq3QEgrn2FB3eEDqwCFvwjgJpFvweZcWXcb6btHLKyoJjYtfb8ROMOCkVZQtRx5cPGfM0chEjXYnBUxMsBtG408ou5QeDbAJkpCeI42CeFRm0GEb_v6gxzWgZAlqYswk4A0v0htfgRn8c6JxcREROgRNcfDSBA9JAEFLCcIoAPIPbYLhRY1AREAhNujESfzJJ5por3nepT_6t5L4YnhFOMrOLryGu-dvM-lcbtQmwlQIi5Vaky8VPai4ljETuLgtjkBxabf38YcnnEwrThff4mwIKIyS95FacBTPxOFTc9PoNxL8DsLm7HW93tHu2xKOe-zo19DJxjcRaWZ2xwPUNAHA1RWT2TCL4QE3amGxP3k4xmPCy2noUeqb2dfNIqLAOHOSMdZ97nlOqbuQB7RxsTo7f9hiM6PwqkLf8uZdHWHsix7y6RpA_Yiz8SDvLXURbrEVQmrD4_riwIjpJroLgx9H4mDLZlgb5Dho8eNZLMBL2mbrzcTpa9rsG0jsYizjIjdpVpo-z4_5tZKDkPN2eLmpe8K_h8cLHQomwyHELEg_6r6Z5C_T8zq1DIcNAOnu3aSv91jL8rcSa4LkIloDRxRVApVClx1VX56cghwFcF_Xemf-o57aCbxKJxnFDMzCXFgdsLSWds4GOYkbL1pDpw7Mu_nMx0148VHyW3dhMTPOYeRhH__cGB85WS49RnG2gTbClCVKlVql4ZwR7hYaYMDuJeYXEdYRxbxly9CIJB2DSvcvdUFONJu3QqD4HBpVM2v2Qnkv2BFTAHSW0hHqcqndnoOHlhliCe27ll_RtGxWzOObGmMmtgRewIsDc00N5MOH7PTcbzq0bzj6NQlZ9pcJs-Gz04sqf1iov-PD6qsSzf2z6qnjSs-Ejlj_B5Pfmt8ynTwFbAxD34kadh4M8mOX-_zHgnmfiqcgAzngrcETD2_OgJhVKg4I3huGD-IBXc177j-EANfAIc_vz12MOe3lcKnr5h9QYL_wlTx7oFWlMUsUHwUYLmgP1cJjzaHyXGdp1sfdmV1WjhxXKL9kEPMIlFN6igBHCjqE4gz0fLFxDyXOu5G7ROkCB87VzKGqTJnbneJ6vBgKBRgDaPgU4so1pIcuVsrmq42ta8mctKJfsR0o99JxxWiiExsux9g_XXz4XCoQ9LYD_Ul1Dz4TLDbp43xifXYjygSSjvZTj7OjUNT75NdU3JP02H0HqjxwwdGYy5tsojN2HJJdNM0i9XvcjP98OIjXd4wc2E5xg.QDXvkU35n-U0snZ_h9GKSo1Q_3HzVhL44pDeULM9-Uc\",\"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\":1776124289299},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyNTc5MCwiaWF0IjoxNzc2MTIyNDkwLCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiI2MzViNjJhZi05NmI1LTQzZjMtOWIxZC01NDVkNWMwYjcxZDEiLCJhdF9oYXNoIjoiaDJHRlFiU0NtM1pHMk5STGgtS2hJZyJ9.GmouLQf3mjoAXANjyjPKiK3vMM4nIc14V7p-WKDDnaLfOABPqNDRg_4nbCTaJ_ILgQcFkX_lm-GMlo9g6ibLbEnq8Stxs15DamLsf4SdGFL63o7UGqGIiqA_maVCMkLly1Y6RQrgijqEFlVL4vLFOM--qt9AHoHMJD7TXjjnMwcY7ID-61SLx-bcbjrxcGix9ISOmH74DMYQaI3wuY_pwre9EaxuaX2jI2kEx_T3G9_BaJhmObMVPB1JAbjPYzJU-vvy2KFXSGiR-NrZY62rP-wdjRfPf6SSSYgoss8uqwl7NymIzxPBI95mx2Qkley_zQGVgp2unhUXL2yQL605lw\"},\"dpopKeyThumbprint\":\"EBzFLNz4pOAbecSIIxZqr-fm0NVvCkAGAwKQsnsNoKk\",\"issuedAtEpochMs\":1776122490300,\"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\":1776122490000,\"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}" + ], + [ + "stellaops.theme", + "system" + ], + [ + "stellaops.auth.session.info", + "{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"expiresAtEpochMs\":1776124289299,\"issuedAtEpochMs\":1776122490300,\"dpopKeyThumbprint\":\"EBzFLNz4pOAbecSIIxZqr-fm0NVvCkAGAwKQsnsNoKk\",\"tenantId\":\"demo-prod\"}" + ], + [ + "stellaops.sidebar.preferences", + "{\"sidebarCollapsed\":false,\"collapsedGroups\":[\"evidence\",\"setup-admin\"],\"collapsedSections\":[]}" + ] + ], + "sessionStorageEntries": [ + [ + "stellaops.auth.session.full", + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyNDI5MCwiaWF0IjoxNzc2MTIyNDkwLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiOTU2ZjljNGUtNGVmMi00ODU0LTg0NTEtNTNiM2UwZTllMzc5Iiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMjI0OTAsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.SjscyX0IrOxirujiUezIVujTNN107P4A1SILVke6kF8sQPS3XC_0u3tIQKkEQzcDdmolLot-iR408Wm2uMIFKhZK4717tw3svwa48KsWSUoiW-fNErDjlPyVGVtzLmykdJsooqwBusoLJe2PwsJj0J3kkpT8YVJMm_AW-OEZxNfvTz_EM-I2ZVF32ErW4waWswbO_5CaNHziDNXlEsyT7eIEYVGvVY2UAV_Dr_VEXd-vvrXlf6t2onvXBpRr5bqsQOctCnV7aPkZqgew9GDPdeOtqr17l-uPs6O8KKKv5vTrj_YLNlBeM9DjmqYA6i07IWoOAx-GOtmV2a9KGXkQ-w\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.PGUaV_kPUQLr-BlrvYwSwQ7VZl5V_kUg8Yb3Q0RWjxvOcGjGIykdQvOrrTnfWk_U0EG-WWKY8HIjY7zGLVkMB4NkfFGN9-m7_JIDbvd50SBnYLeXC95HZPf0t0eJ45Prv5cvRTyt63EzHtHs_ttbp6ZLBQhqd_rmyop_q1AlKlfS8zcB45ZAlnpMBmiMpuQfxsOs9SzNvsbKvUF4UBq9VChgps4bCv3RDzOOpZbvhNTtA53af9nwoavqoB6utLqF5N7aXAC12XBMs2a2NVmdRMP3W4T-sZ1ksdhhKORbQdspXqu-PBzTuJ4Lq-HjWVZtQdO4T91I3fQb8zNXIScH7A.vk3i21BvJsqJvGklE3WW9Q.txCN69BgfMIdy9ghjTFQDEkgtI4VfJpz3-0oNNcePB_BeJqaaJryF_eNYXhUvFIz7SfRbCbjFPhS6wD_29YephOxZ6I9TyjpuncbVNila0ohV3eTiAzx6ZgVnJZmEUja3UU_nFTrJLZws2LXJU91SmGkq5-tQv4iPJMrIKkVTtUUOKbGT8gtTzQaSPAoU0rLk7vfmDKIKGm9yO-TKcgXCxny2odkSn87bfENLIaLC5uYbtVxbJEY_2oT0_ytuMEurnKcsgjv1FaVFLg7t2I1LgNIlKVfvCfMh1Q4k7wtitQhy_DAzgoo522-j4RWRqhvRrjAxG-PCVXHAqZlMakL81XCLdX2oMLgr4Aba_9g-APvG-gVvjOcNQzUuVBw5ThD3ESJEXeS-w3V0cZm66hSMQ5SjWmXo1fbpGD8V8wYb5UlOZvo1ZLEV3f4ao2F0GLhAHD2cB-VwX-SatfBOPvPRBgvECGI9fBG9qGn3gQ_RK7rh-HhH9tEsW5uCaphZpjTCvUVgJmUMQztXbS6yCfmQqQa0AL3y9fWQbtn121xbbduHS8R_0z-fNMfkS3HlI8AG7IBkYXyohezkhGT6HlIfKzpFBWQKmNKioe6HA-h5XZMLVtGABrKJmUm3omhS1i3rAFOZ4H3TlLpjnv3aVjZONSA2KlJ6UnAIwo8x3j_T4WHtKfxD-e24K_5rhAkhYql6vXZAhaQxz9NZoubrxeQgr7pJRj9xJmd63fricLcWDV56cMwQXYgNiQZ_kz3-uUKdS6pGqKCvnj2XSalpTjGzmAVol5kbNCzN7RysJlJUgbPunKOvwEoAZ3Dc1KDp056a6Ufw9NSp43j8YDF0hOW6oMasciFXCZnkbmlHeeH0WZs2q1dAWNFPP5c_avAoZZmNfBTbDrOsI75IvfX5QV2BDozwv7lIe3kBVeVeytHPn8DJtZc07aEpjFsItD0y4eko3MGGHt7GSDABpsuO3SsKIYNyZKLlCL1a90TbTRtoq473bZFKkCzKuKEFPZzWahp4D1gi19tRGlybpoaR0RfOHRT9ejF9heWbqykC7WrB2VsqIYzxm5GecjKL9JMlzC4u7cX8jRDu1MJcux0hEc1Vltztj7aFklgxRwK-2lA65T_X1dtF3WDG1UzuU_B4IKzRTr4Il39W7bdKKlrshp8zgmmYxXEvHZTUmVBNUU9V9haEXfYT92vcHZtDD8NNoKa2-asNI7jBFLOFbyLXXsed8HC6lLl8CU6DzO27TntztthxNxhSv2yzH6-TMv5fNtt_fZlP7ID1RjpqwxUqn9K8mGP6kyKfg5MfbytCQi6dFJqNgQbequExareeCb4G2cyP2vOYnzSyQrTnRnDsHqXiyANZzJbJXdI0FoVKuLUU8AlmCsCFWr35LrUlf_SyQdmV6jp-BFUV9gv5N5y89oragfI6SH6gacHG_c77VHegfpJMV309_h_srsmARpcWrA_Y9daO_VJjGPe0qos652xW7hs2qn_orD2O4VdbNgdP_KmVla0PzeTcx7pGIUlAFmD_xSDc52AMDmwk3cX_n4RxdHzGvyAJasRUKR2lfqRKLV5JHkFOUkGR5xQPgfEep68-mhnHRaBw3kE0kzGdBni5lpT8tBa3IK7ShuWp81B09cPKEbsGxqB9LPoff4sXRBF3vZKjvkx1lfyYKARtY1A1FNj3iQNvi8gFI3gy9fzSttpz4X1khh0S_mR6ou6r-aksCCK5TGx3gt_n9tXFXNJZ79wtsTlYU8V5AesRrEs6qKGvo2usx8um2P7OqrC_iwMqgF2YtUZe-OrLV_J5d6RrVXQGN9D6YMDZsJ0Dxo--ff7BgglXVjCKChdzA1Fzg6sLOKnL5SEobrC8SFDLMStK23QM-71b4VB2jhLVAV4HdErT6QpH1QIUhtQZtnMDFgwNXC0hemBIxeQjFc6q18K9Hv_c2TjoJ4QipIQI_9tGSE-0-VP7FCIlHEe3ONK7mihvx1ACYiWzd84xj21Wxi0aS-bAmvz9qJykLr9ct-O2bnP6HDdkquweCgxQ_pHsUIAWE87KkTboXXTSvAcBb9Mr7NI8wLHbrSJ3LCUtFg_RyGdEFW3B4gp-NuC-YZfM8X9iUvkqal80Fxe8onqWAvWtVnyfLBCxECgdiZgLgOvODBLHJUiFK5qcE4KgK--XOj9qs_yiUkuXrw7P43rCu1WpmoxdnvULGlfDvZg3O-AiB1ncDuz1YqxjMnMRBl5P01lQur-6VHRMTav4cxpbXiKdc2nw_R1ix_R7q2mefmXlKKRa3MiZiZFrdeTtexclWIFKMzBl6YGl7fPJccCyqw7YBBOBVj1Az6-KkLYxlATgErBYcfq93TYLpgV5Q8-8nFjTmNddcfIWLj3D8jRoT0E4PlzbfUnDWJaxQlrzkUdoq_SIIvBmRLT3n439_xjn7aTlfGY8TtAb4Ev8NKsBwXRd1IzdS2f3EMS2NHazDYMjhITFg92IqyL9w88qlpV90EqvzmeDvpKnFPlYzeUf8fy0IHHiD-oeKOGpXNrnE8Uh-fYUWMHMVcIKQ7Ag5VqmdJGuz3StHzva-SXa46pPrcx9n9Eso9qd72Jx38bZoYWKz4kfB1wSinEl6JTzJTOPCzHxJFSKYhqlCvuMvIDtvyRrOVhaN8z-h1V4OLZN3og3TtK6Ln6I40AXZjByK1naRG9yK_lJlzOGXkTlj_4vkpqazdbiDQBawIGNNJi8T7ZrzF8rvfnGOrsdNn5V833H53hufWSSnuFMOyWwQlxDKaPEBz0DYt2wW8cCxARG5NGQdyUw744ic9bfMS5zaGrGYZk-znteQP8k0OSeDEg49lGhFpeipkCWJkhUFVxfu0nv6H06PwlP9RdxBEkYVS_1D-P7Xow4fj47C3o5Scpgw4eRsnXu0jvp3fPBYTtaeCYYpCeri4EqVeYF3bVK0x04A7_asi2CGRd7Bc-1CYgeJ-gdB8Rh58u5Q6rLHs5D6ZHlyrtZH2bu_rZxMSETXf4bJBBI8umOUdzBWIv2P_Ww_uUVyCppvMdNeGDt8IZKM9CkrYk_xDguUH7AN-bZFHNt82idPTDVaD6BMeOnoqsvLhY22p3dzOp-oTqpdXTdq31lWgxo3xC4UbOLdESz0G1vBuRVoYnbh0zw5RTQrQRWXmeTBu81qAbM_hxrbsGCAF0zBQmaJqAmuxsAGoGTs1etz9_0VG6qX-DBFlpgoHTP1VA_tXbJTO3r52cTyaheX4xfZ8f19hzGu56umAh0cIxzKvdJetskCn8vFmJBEGicqIJu5oxEe_p23GLFQd8HSdG2MbmPd8OBuSiEeDUvmVwfmbkfQkODNGheGL6a-d9C_b6a-6LXpFI8erjxs2ruDINAkmd15OLOjUHzY66aTSuPuGlDLRwBuycQAvwuIjQb7hTfwxjoZGXhc_IsMhpJoj5zAOzYTE7gf_Dg-u1pmpXd0x6ySWv4Ms1yC-voilS8sdCoVNEmudKAJXY1cd29X2ILAQ09fq3QEgrn2FB3eEDqwCFvwjgJpFvweZcWXcb6btHLKyoJjYtfb8ROMOCkVZQtRx5cPGfM0chEjXYnBUxMsBtG408ou5QeDbAJkpCeI42CeFRm0GEb_v6gxzWgZAlqYswk4A0v0htfgRn8c6JxcREROgRNcfDSBA9JAEFLCcIoAPIPbYLhRY1AREAhNujESfzJJ5por3nepT_6t5L4YnhFOMrOLryGu-dvM-lcbtQmwlQIi5Vaky8VPai4ljETuLgtjkBxabf38YcnnEwrThff4mwIKIyS95FacBTPxOFTc9PoNxL8DsLm7HW93tHu2xKOe-zo19DJxjcRaWZ2xwPUNAHA1RWT2TCL4QE3amGxP3k4xmPCy2noUeqb2dfNIqLAOHOSMdZ97nlOqbuQB7RxsTo7f9hiM6PwqkLf8uZdHWHsix7y6RpA_Yiz8SDvLXURbrEVQmrD4_riwIjpJroLgx9H4mDLZlgb5Dho8eNZLMBL2mbrzcTpa9rsG0jsYizjIjdpVpo-z4_5tZKDkPN2eLmpe8K_h8cLHQomwyHELEg_6r6Z5C_T8zq1DIcNAOnu3aSv91jL8rcSa4LkIloDRxRVApVClx1VX56cghwFcF_Xemf-o57aCbxKJxnFDMzCXFgdsLSWds4GOYkbL1pDpw7Mu_nMx0148VHyW3dhMTPOYeRhH__cGB85WS49RnG2gTbClCVKlVql4ZwR7hYaYMDuJeYXEdYRxbxly9CIJB2DSvcvdUFONJu3QqD4HBpVM2v2Qnkv2BFTAHSW0hHqcqndnoOHlhliCe27ll_RtGxWzOObGmMmtgRewIsDc00N5MOH7PTcbzq0bzj6NQlZ9pcJs-Gz04sqf1iov-PD6qsSzf2z6qnjSs-Ejlj_B5Pfmt8ynTwFbAxD34kadh4M8mOX-_zHgnmfiqcgAzngrcETD2_OgJhVKg4I3huGD-IBXc177j-EANfAIc_vz12MOe3lcKnr5h9QYL_wlTx7oFWlMUsUHwUYLmgP1cJjzaHyXGdp1sfdmV1WjhxXKL9kEPMIlFN6igBHCjqE4gz0fLFxDyXOu5G7ROkCB87VzKGqTJnbneJ6vBgKBRgDaPgU4so1pIcuVsrmq42ta8mctKJfsR0o99JxxWiiExsux9g_XXz4XCoQ9LYD_Ul1Dz4TLDbp43xifXYjygSSjvZTj7OjUNT75NdU3JP02H0HqjxwwdGYy5tsojN2HJJdNM0i9XvcjP98OIjXd4wc2E5xg.QDXvkU35n-U0snZ_h9GKSo1Q_3HzVhL44pDeULM9-Uc\",\"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\":1776124289299},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyNTc5MCwiaWF0IjoxNzc2MTIyNDkwLCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiI2MzViNjJhZi05NmI1LTQzZjMtOWIxZC01NDVkNWMwYjcxZDEiLCJhdF9oYXNoIjoiaDJHRlFiU0NtM1pHMk5STGgtS2hJZyJ9.GmouLQf3mjoAXANjyjPKiK3vMM4nIc14V7p-WKDDnaLfOABPqNDRg_4nbCTaJ_ILgQcFkX_lm-GMlo9g6ibLbEnq8Stxs15DamLsf4SdGFL63o7UGqGIiqA_maVCMkLly1Y6RQrgijqEFlVL4vLFOM--qt9AHoHMJD7TXjjnMwcY7ID-61SLx-bcbjrxcGix9ISOmH74DMYQaI3wuY_pwre9EaxuaX2jI2kEx_T3G9_BaJhmObMVPB1JAbjPYzJU-vvy2KFXSGiR-NrZY62rP-wdjRfPf6SSSYgoss8uqwl7NymIzxPBI95mx2Qkley_zQGVgp2unhUXL2yQL605lw\"},\"dpopKeyThumbprint\":\"EBzFLNz4pOAbecSIIxZqr-fm0NVvCkAGAwKQsnsNoKk\",\"issuedAtEpochMs\":1776122490300,\"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\":1776122490000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" + ], + [ + "stellaops:wasEverAuth", + "true" + ] + ] + }, + "events": { + "consoleErrors": [], + "requestFailures": [], + "responseErrors": [] + }, + "statePath": "C:\\dev\\New folder\\git.stella-ops.org\\src\\Web\\StellaOps.Web\\output\\playwright\\live-integrations-ui-bootstrap.state.json" +} diff --git a/src/Web/StellaOps.Web/output/playwright/live-integrations-ui-bootstrap.json b/src/Web/StellaOps.Web/output/playwright/live-integrations-ui-bootstrap.json new file mode 100644 index 000000000..d00542c73 --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-integrations-ui-bootstrap.json @@ -0,0 +1,1322 @@ +{ + "generatedAtUtc": "2026-04-13T23:21:33.377Z", + "baseUrl": "https://stella-ops.local", + "scopeQuery": "tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "includeGitLab": true, + "gitLabStageSecrets": true, + "integrations": [ + { + "name": "Local Harbor Fixture", + "route": "registry", + "provider": "Harbor", + "endpoint": "http://harbor-fixture.stella-ops.local", + "action": "existing", + "integrationId": "44bd29b1-dafd-44f0-87fd-c88daee7e544", + "detailActions": { + "openedHealthTab": false, + "ranTestConnection": false, + "ranHealthCheck": false + }, + "verification": { + "testStatusCode": 200, + "healthStatusCode": 200, + "test": { + "integrationId": "44bd29b1-dafd-44f0-87fd-c88daee7e544", + "success": true, + "message": "Harbor connection successful", + "details": { + "endpoint": "http://harbor-fixture.stella-ops.local", + "status": "healthy", + "version": "2.10.0" + }, + "duration": "00:00:00.0018349", + "testedAt": "2026-04-13T23:21:36.1995951+00:00" + }, + "health": { + "integrationId": "44bd29b1-dafd-44f0-87fd-c88daee7e544", + "status": 1, + "message": "Harbor status: healthy", + "details": { + "core": "healthy", + "jobservice": "healthy", + "registry": "healthy" + }, + "checkedAt": "2026-04-13T23:21:35.398041+00:00", + "duration": "00:00:00.0019658" + } + }, + "snapshot": { + "label": "Local Harbor Fixture", + "url": "https://stella-ops.local/setup/integrations/44bd29b1-dafd-44f0-87fd-c88daee7e544?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Integration Detail - StellaOps", + "heading": "Integrations", + "notices": [] + } + }, + { + "name": "Local Docker Registry", + "route": "registry", + "provider": "Docker Registry / Hub", + "endpoint": "http://registry.stella-ops.local:5000", + "action": "existing", + "integrationId": "bbeffeb9-79ba-47cf-a996-513c422bc4c8", + "detailActions": { + "openedHealthTab": false, + "ranTestConnection": false, + "ranHealthCheck": false + }, + "verification": { + "testStatusCode": 200, + "healthStatusCode": 200, + "test": { + "integrationId": "bbeffeb9-79ba-47cf-a996-513c422bc4c8", + "success": true, + "message": "Docker Registry connection successful", + "details": { + "endpoint": "http://registry.stella-ops.local:5000", + "apiVersion": "registry/2.0" + }, + "duration": "00:00:00.0047461", + "testedAt": "2026-04-13T23:21:36.2032747+00:00" + }, + "health": { + "integrationId": "bbeffeb9-79ba-47cf-a996-513c422bc4c8", + "status": 1, + "message": "Docker Registry is available", + "details": { + "repositories": "0" + }, + "checkedAt": "2026-04-13T23:21:36.2031763+00:00", + "duration": "00:00:00.0027885" + } + }, + "snapshot": { + "label": "Local Docker Registry", + "url": "https://stella-ops.local/setup/integrations/bbeffeb9-79ba-47cf-a996-513c422bc4c8?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Integration Detail - StellaOps", + "heading": "Integrations", + "notices": [] + } + }, + { + "name": "Local Nexus Registry", + "route": "registry", + "provider": "Nexus", + "endpoint": "http://nexus.stella-ops.local:8081", + "action": "existing", + "integrationId": "263befd6-b2ee-4531-bd8e-7ff6b968b42b", + "detailActions": { + "openedHealthTab": false, + "ranTestConnection": false, + "ranHealthCheck": false + }, + "verification": { + "testStatusCode": 200, + "healthStatusCode": 200, + "test": { + "integrationId": "263befd6-b2ee-4531-bd8e-7ff6b968b42b", + "success": true, + "message": "Nexus connection successful", + "details": { + "endpoint": "http://nexus.stella-ops.local:8081", + "statusCode": "200" + }, + "duration": "00:00:00.0067601", + "testedAt": "2026-04-13T23:21:40.3025535+00:00" + }, + "health": { + "integrationId": "263befd6-b2ee-4531-bd8e-7ff6b968b42b", + "status": 1, + "message": "Nexus is available and ready", + "details": { + "statusCode": "200" + }, + "checkedAt": "2026-04-13T23:21:40.3156215+00:00", + "duration": "00:00:00.0166765" + } + }, + "snapshot": { + "label": "Local Nexus Registry", + "url": "https://stella-ops.local/setup/integrations/263befd6-b2ee-4531-bd8e-7ff6b968b42b?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Integration Detail - StellaOps", + "heading": "Integrations", + "notices": [] + } + }, + { + "name": "Local GitHub App Fixture", + "route": "scm", + "provider": "GitHub App", + "endpoint": "http://github-app-fixture.stella-ops.local", + "action": "existing", + "integrationId": "5c2d7215-ee04-4a8d-b213-03cd834ee799", + "detailActions": { + "openedHealthTab": false, + "ranTestConnection": false, + "ranHealthCheck": false + }, + "verification": { + "testStatusCode": 200, + "healthStatusCode": 200, + "test": { + "integrationId": "5c2d7215-ee04-4a8d-b213-03cd834ee799", + "success": true, + "message": "Connected as GitHub App: Stella QA GitHub App", + "details": { + "endpoint": "http://github-app-fixture.stella-ops.local", + "appName": "Stella QA GitHub App", + "appId": "424242", + "slug": "stella-qa-app" + }, + "duration": "00:00:00.0018491", + "testedAt": "2026-04-13T23:21:41.8069526+00:00" + }, + "health": { + "integrationId": "5c2d7215-ee04-4a8d-b213-03cd834ee799", + "status": 1, + "message": "Rate limit: 4991/5000 remaining (0% used)", + "details": { + "remaining": "4991", + "limit": "5000", + "percentUsed": "0" + }, + "checkedAt": "2026-04-13T23:21:41.9964213+00:00", + "duration": "00:00:00.0023199" + } + }, + "snapshot": { + "label": "Local GitHub App Fixture", + "url": "https://stella-ops.local/setup/integrations/5c2d7215-ee04-4a8d-b213-03cd834ee799?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Integration Detail - StellaOps", + "heading": "Integrations", + "notices": [] + } + }, + { + "name": "Local Gitea Server", + "route": "scm", + "provider": "Gitea", + "endpoint": "http://gitea.stella-ops.local:3000", + "action": "existing", + "integrationId": "efce990e-5381-41a0-8732-69756003fe91", + "detailActions": { + "openedHealthTab": false, + "ranTestConnection": false, + "ranHealthCheck": false + }, + "verification": { + "testStatusCode": 200, + "healthStatusCode": 200, + "test": { + "integrationId": "efce990e-5381-41a0-8732-69756003fe91", + "success": true, + "message": "Gitea connection successful", + "details": { + "endpoint": "http://gitea.stella-ops.local:3000", + "version": "1.22.6" + }, + "duration": "00:00:00.0022927", + "testedAt": "2026-04-13T23:21:45.4981872+00:00" + }, + "health": { + "integrationId": "efce990e-5381-41a0-8732-69756003fe91", + "status": 1, + "message": "Gitea is running version 1.22.6", + "details": { + "version": "1.22.6" + }, + "checkedAt": "2026-04-13T23:21:45.4980941+00:00", + "duration": "00:00:00.0012683" + } + }, + "snapshot": { + "label": "Local Gitea Server", + "url": "https://stella-ops.local/setup/integrations/efce990e-5381-41a0-8732-69756003fe91?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Integration Detail - StellaOps", + "heading": "Integrations", + "notices": [] + } + }, + { + "name": "Local Jenkins", + "route": "ci", + "provider": "Jenkins", + "endpoint": "http://jenkins.stella-ops.local:8080", + "action": "existing", + "integrationId": "5fafad2a-944c-4543-bcfe-fe60c303a744", + "detailActions": { + "openedHealthTab": false, + "ranTestConnection": false, + "ranHealthCheck": false + }, + "verification": { + "testStatusCode": 200, + "healthStatusCode": 200, + "test": { + "integrationId": "5fafad2a-944c-4543-bcfe-fe60c303a744", + "success": true, + "message": "Jenkins connection successful", + "details": { + "endpoint": "http://jenkins.stella-ops.local:8080", + "mode": "NORMAL", + "nodeDescription": "the Jenkins controller's built-in node" + }, + "duration": "00:00:00.0073178", + "testedAt": "2026-04-13T23:21:49.6146059+00:00" + }, + "health": { + "integrationId": "5fafad2a-944c-4543-bcfe-fe60c303a744", + "status": 1, + "message": "Jenkins mode: NORMAL", + "details": { + "mode": "NORMAL", + "nodeDescription": "the Jenkins controller's built-in node", + "numExecutors": "2" + }, + "checkedAt": "2026-04-13T23:21:49.6145075+00:00", + "duration": "00:00:00.0066568" + } + }, + "snapshot": { + "label": "Local Jenkins", + "url": "https://stella-ops.local/setup/integrations/5fafad2a-944c-4543-bcfe-fe60c303a744?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Integration Detail - StellaOps", + "heading": "Integrations", + "notices": [] + } + }, + { + "name": "Local eBPF Runtime Host", + "route": "host", + "provider": "eBPF Agent", + "endpoint": "http://runtime-host-fixture.stella-ops.local", + "action": "existing", + "integrationId": "1cc18b24-c833-4a82-8447-d6c5cd130194", + "detailActions": { + "openedHealthTab": false, + "ranTestConnection": false, + "ranHealthCheck": false + }, + "verification": { + "testStatusCode": 200, + "healthStatusCode": 200, + "test": { + "integrationId": "1cc18b24-c833-4a82-8447-d6c5cd130194", + "success": true, + "message": "eBPF agent connection successful", + "details": { + "endpoint": "http://runtime-host-fixture.stella-ops.local", + "version": "0.9.0", + "agent": "ebpf", + "probes_loaded": "12", + "events_per_second": "450" + }, + "duration": "00:00:00.0010586", + "testedAt": "2026-04-13T23:21:51.2052099+00:00" + }, + "health": { + "integrationId": "1cc18b24-c833-4a82-8447-d6c5cd130194", + "status": 1, + "message": "eBPF agent status: healthy", + "details": { + "agent": "ebpf", + "version": "0.9.0", + "kernel": "6.1.0", + "probes_loaded": "12" + }, + "checkedAt": "2026-04-13T23:21:51.2070859+00:00", + "duration": "00:00:00.0018575" + } + }, + "snapshot": { + "label": "Local eBPF Runtime Host", + "url": "https://stella-ops.local/setup/integrations/1cc18b24-c833-4a82-8447-d6c5cd130194?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Integration Detail - StellaOps", + "heading": "Integrations", + "notices": [] + } + }, + { + "name": "Local StellaOps Mirror", + "route": "feed", + "provider": "StellaOps Mirror", + "endpoint": "http://concelier.stella-ops.local", + "action": "existing", + "integrationId": "23cc3ac6-dbd2-4b3f-9690-0d0f089f76a0", + "detailActions": { + "openedHealthTab": false, + "ranTestConnection": false, + "ranHealthCheck": false + }, + "verification": { + "testStatusCode": 200, + "healthStatusCode": 200, + "test": { + "integrationId": "23cc3ac6-dbd2-4b3f-9690-0d0f089f76a0", + "success": true, + "message": "Feed mirror connection successful", + "details": { + "endpoint": "http://concelier.stella-ops.local", + "provider": "StellaOpsMirror" + }, + "duration": "00:00:00.0040896", + "testedAt": "2026-04-13T23:21:53.903769+00:00" + }, + "health": { + "integrationId": "23cc3ac6-dbd2-4b3f-9690-0d0f089f76a0", + "status": 1, + "message": "Feed mirror service is healthy", + "details": { + "provider": "StellaOpsMirror" + }, + "checkedAt": "2026-04-13T23:21:54.006458+00:00", + "duration": "00:00:00.0013905" + } + }, + "snapshot": { + "label": "Local StellaOps Mirror", + "url": "https://stella-ops.local/setup/integrations/23cc3ac6-dbd2-4b3f-9690-0d0f089f76a0?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Integration Detail - StellaOps", + "heading": "Integrations", + "notices": [] + } + }, + { + "name": "Local NVD Mirror", + "route": "feed", + "provider": "NVD Mirror", + "endpoint": "http://concelier.stella-ops.local", + "action": "existing", + "integrationId": "e6aa18c7-0bc8-4d67-83aa-63a64ffd7c2e", + "detailActions": { + "openedHealthTab": false, + "ranTestConnection": false, + "ranHealthCheck": false + }, + "verification": { + "testStatusCode": 200, + "healthStatusCode": 200, + "test": { + "integrationId": "e6aa18c7-0bc8-4d67-83aa-63a64ffd7c2e", + "success": true, + "message": "Feed mirror connection successful", + "details": { + "endpoint": "http://concelier.stella-ops.local", + "provider": "NvdMirror" + }, + "duration": "00:00:00.0014106", + "testedAt": "2026-04-13T23:21:57.8216588+00:00" + }, + "health": { + "integrationId": "e6aa18c7-0bc8-4d67-83aa-63a64ffd7c2e", + "status": 1, + "message": "Feed mirror service is healthy", + "details": { + "provider": "NvdMirror" + }, + "checkedAt": "2026-04-13T23:21:57.9004974+00:00", + "duration": "00:00:00.0022576" + } + }, + "snapshot": { + "label": "Local NVD Mirror", + "url": "https://stella-ops.local/setup/integrations/e6aa18c7-0bc8-4d67-83aa-63a64ffd7c2e?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Integration Detail - StellaOps", + "heading": "Integrations", + "notices": [] + } + }, + { + "name": "Local OSV Mirror", + "route": "feed", + "provider": "OSV Mirror", + "endpoint": "http://concelier.stella-ops.local", + "action": "existing", + "integrationId": "54844d7d-e209-494a-a81d-e8bff2e22f69", + "detailActions": { + "openedHealthTab": false, + "ranTestConnection": false, + "ranHealthCheck": false + }, + "verification": { + "testStatusCode": 200, + "healthStatusCode": 200, + "test": { + "integrationId": "54844d7d-e209-494a-a81d-e8bff2e22f69", + "success": true, + "message": "Feed mirror connection successful", + "details": { + "endpoint": "http://concelier.stella-ops.local", + "provider": "OsvMirror" + }, + "duration": "00:00:00.0014296", + "testedAt": "2026-04-13T23:22:01.5987037+00:00" + }, + "health": { + "integrationId": "54844d7d-e209-494a-a81d-e8bff2e22f69", + "status": 1, + "message": "Feed mirror service is healthy", + "details": { + "provider": "OsvMirror" + }, + "checkedAt": "2026-04-13T23:22:01.6992527+00:00", + "duration": "00:00:00.0026490" + } + }, + "snapshot": { + "label": "Local OSV Mirror", + "url": "https://stella-ops.local/setup/integrations/54844d7d-e209-494a-a81d-e8bff2e22f69?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Integration Detail - StellaOps", + "heading": "Integrations", + "notices": [] + } + }, + { + "name": "Local Vault", + "route": "secrets", + "provider": "HashiCorp Vault", + "endpoint": "http://vault.stella-ops.local:8200", + "action": "existing", + "integrationId": "c80ae6b1-d20a-410b-9f82-7bfe88ac0a99", + "detailActions": { + "openedHealthTab": false, + "ranTestConnection": false, + "ranHealthCheck": false + }, + "verification": { + "testStatusCode": 200, + "healthStatusCode": 200, + "test": { + "integrationId": "c80ae6b1-d20a-410b-9f82-7bfe88ac0a99", + "success": true, + "message": "Vault connection successful", + "details": { + "endpoint": "http://vault.stella-ops.local:8200", + "version": "1.18.5", + "initialized": "true", + "sealed": "false" + }, + "duration": "00:00:00.0028430", + "testedAt": "2026-04-13T23:22:03.201238+00:00" + }, + "health": { + "integrationId": "c80ae6b1-d20a-410b-9f82-7bfe88ac0a99", + "status": 1, + "message": "Vault status: initialized=True, sealed=False", + "details": { + "initialized": "true", + "sealed": "false", + "version": "1.18.5", + "clusterName": "vault-cluster-42096618" + }, + "checkedAt": "2026-04-13T23:22:03.3029215+00:00", + "duration": "00:00:00.0013886" + } + }, + "snapshot": { + "label": "Local Vault", + "url": "https://stella-ops.local/setup/integrations/c80ae6b1-d20a-410b-9f82-7bfe88ac0a99?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Integration Detail - StellaOps", + "heading": "Integrations", + "notices": [] + } + }, + { + "name": "Local Consul", + "route": "secrets", + "provider": "HashiCorp Consul", + "endpoint": "http://consul.stella-ops.local:8500", + "action": "existing", + "integrationId": "8634f246-ab4e-4db4-991b-9ef3f6fd8ca3", + "detailActions": { + "openedHealthTab": false, + "ranTestConnection": false, + "ranHealthCheck": false + }, + "verification": { + "testStatusCode": 200, + "healthStatusCode": 200, + "test": { + "integrationId": "8634f246-ab4e-4db4-991b-9ef3f6fd8ca3", + "success": true, + "message": "Consul connection successful", + "details": { + "endpoint": "http://consul.stella-ops.local:8500", + "leader": "172.19.0.18:8300" + }, + "duration": "00:00:00.0035017", + "testedAt": "2026-04-13T23:22:04.9177441+00:00" + }, + "health": { + "integrationId": "8634f246-ab4e-4db4-991b-9ef3f6fd8ca3", + "status": 1, + "message": "Consul agent healthy: 75ec602aa579", + "details": { + "nodeName": "75ec602aa579", + "datacenter": "dc1" + }, + "checkedAt": "2026-04-13T23:22:04.931915+00:00", + "duration": "00:00:00.0027770" + } + }, + "snapshot": { + "label": "Local Consul", + "url": "https://stella-ops.local/setup/integrations/8634f246-ab4e-4db4-991b-9ef3f6fd8ca3?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Integration Detail - StellaOps", + "heading": "Integrations", + "notices": [] + } + }, + { + "name": "Local MinIO", + "route": "storage", + "provider": "S3-Compatible Storage", + "endpoint": "http://minio.stella-ops.local:9000", + "action": "existing", + "integrationId": "afe36580-b1aa-4930-b81d-a1b800ee3d76", + "detailActions": { + "openedHealthTab": false, + "ranTestConnection": false, + "ranHealthCheck": false + }, + "verification": { + "testStatusCode": 200, + "healthStatusCode": 200, + "test": { + "integrationId": "afe36580-b1aa-4930-b81d-a1b800ee3d76", + "success": true, + "message": "S3-compatible storage probe succeeded.", + "details": { + "probeUri": "http://minio.stella-ops.local:9000/minio/health/live", + "statusCode": "200" + }, + "duration": "00:00:00.0038906", + "testedAt": "2026-04-13T23:22:06.8332396+00:00" + }, + "health": { + "integrationId": "afe36580-b1aa-4930-b81d-a1b800ee3d76", + "status": 1, + "message": "S3-compatible storage probe is healthy.", + "details": { + "probeUri": "http://minio.stella-ops.local:9000/minio/health/live", + "statusCode": "200" + }, + "checkedAt": "2026-04-13T23:22:07.0136394+00:00", + "duration": "00:00:00.0012473" + } + }, + "snapshot": { + "label": "Local MinIO", + "url": "https://stella-ops.local/setup/integrations/afe36580-b1aa-4930-b81d-a1b800ee3d76?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Integration Detail - StellaOps", + "heading": "Integrations", + "notices": [] + } + }, + { + "name": "Local GitLab Server", + "route": "scm", + "provider": "GitLab Server", + "endpoint": "http://gitlab.stella-ops.local:8929", + "action": "existing", + "integrationId": "f88b1704-62a5-46cf-8a82-278224de5ddc", + "detailActions": { + "openedHealthTab": false, + "ranTestConnection": false, + "ranHealthCheck": false + }, + "verification": { + "testStatusCode": 200, + "healthStatusCode": 200, + "test": { + "integrationId": "f88b1704-62a5-46cf-8a82-278224de5ddc", + "success": true, + "message": "GitLab connection successful", + "details": { + "endpoint": "http://gitlab.stella-ops.local:8929", + "version": "17.8.1", + "revision": "19fb562cbb8" + }, + "duration": "00:00:00.0987105", + "testedAt": "2026-04-13T23:22:12.0423257+00:00" + }, + "health": { + "integrationId": "f88b1704-62a5-46cf-8a82-278224de5ddc", + "status": 1, + "message": "GitLab is running version 17.8.1", + "details": { + "version": "17.8.1", + "revision": "19fb562cbb8" + }, + "checkedAt": "2026-04-13T23:22:12.0856388+00:00", + "duration": "00:00:00.0378211" + } + }, + "snapshot": { + "label": "Local GitLab Server", + "url": "https://stella-ops.local/setup/integrations/f88b1704-62a5-46cf-8a82-278224de5ddc?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "StellaOps", + "heading": "Integrations", + "notices": [] + } + }, + { + "name": "Local GitLab CI", + "route": "ci", + "provider": "GitLab CI", + "endpoint": "http://gitlab.stella-ops.local:8929", + "action": "existing", + "integrationId": "870ed598-e185-4740-b802-7239719aadeb", + "detailActions": { + "openedHealthTab": false, + "ranTestConnection": false, + "ranHealthCheck": false + }, + "verification": { + "testStatusCode": 200, + "healthStatusCode": 200, + "test": { + "integrationId": "870ed598-e185-4740-b802-7239719aadeb", + "success": true, + "message": "GitLab connection successful", + "details": { + "endpoint": "http://gitlab.stella-ops.local:8929", + "version": "17.8.1", + "revision": "19fb562cbb8" + }, + "duration": "00:00:00.0373208", + "testedAt": "2026-04-13T23:22:14.6702116+00:00" + }, + "health": { + "integrationId": "870ed598-e185-4740-b802-7239719aadeb", + "status": 1, + "message": "GitLab is running version 17.8.1", + "details": { + "version": "17.8.1", + "revision": "19fb562cbb8" + }, + "checkedAt": "2026-04-13T23:22:14.8503528+00:00", + "duration": "00:00:00.0341782" + } + }, + "snapshot": { + "label": "Local GitLab CI", + "url": "https://stella-ops.local/setup/integrations/870ed598-e185-4740-b802-7239719aadeb?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Integration Detail - StellaOps", + "heading": "Integrations", + "notices": [] + } + }, + { + "name": "Local GitLab Container Registry", + "route": "registry", + "provider": "GitLab Container Registry", + "endpoint": "http://gitlab.stella-ops.local:5050", + "action": "existing", + "integrationId": "8156f10f-3a4c-4862-b32b-8d49a80a5603", + "detailActions": { + "openedHealthTab": false, + "ranTestConnection": false, + "ranHealthCheck": false + }, + "verification": { + "testStatusCode": 200, + "healthStatusCode": 200, + "test": { + "integrationId": "8156f10f-3a4c-4862-b32b-8d49a80a5603", + "success": true, + "message": "Docker Registry connection successful", + "details": { + "endpoint": "http://gitlab.stella-ops.local:5050", + "apiVersion": "registry/2.0" + }, + "duration": "00:00:00.0729851", + "testedAt": "2026-04-13T23:22:17.9975316+00:00" + }, + "health": { + "integrationId": "8156f10f-3a4c-4862-b32b-8d49a80a5603", + "status": 1, + "message": "Docker Registry is available", + "details": { + "repositories": "0" + }, + "checkedAt": "2026-04-13T23:22:18.0728393+00:00", + "duration": "00:00:00.1454732" + } + }, + "snapshot": { + "label": "Local GitLab Container Registry", + "url": "https://stella-ops.local/setup/integrations/8156f10f-3a4c-4862-b32b-8d49a80a5603?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Integration Detail - StellaOps", + "heading": "Integrations", + "notices": [] + } + } + ], + "runtime": { + "consoleErrors": [], + "pageErrors": [], + "requestFailures": [ + { + "page": "https://stella-ops.local/setup/integrations/44bd29b1-dafd-44f0-87fd-c88daee7e544?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/tips?route=/setup/integrations/44bd29b1-dafd-44f0-87fd-c88daee7e544&locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/44bd29b1-dafd-44f0-87fd-c88daee7e544?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/platform/preferences/language", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/44bd29b1-dafd-44f0-87fd-c88daee7e544?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/security/findings?severity=critical&disposition=unreviewed&limit=0", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/44bd29b1-dafd-44f0-87fd-c88daee7e544?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/44bd29b1-dafd-44f0-87fd-c88daee7e544?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/context/regions", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/bbeffeb9-79ba-47cf-a996-513c422bc4c8?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/tips?route=/setup/integrations/bbeffeb9-79ba-47cf-a996-513c422bc4c8&locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/bbeffeb9-79ba-47cf-a996-513c422bc4c8?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/bbeffeb9-79ba-47cf-a996-513c422bc4c8?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/platform/preferences/language", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/bbeffeb9-79ba-47cf-a996-513c422bc4c8?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/context/preferences", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/bbeffeb9-79ba-47cf-a996-513c422bc4c8?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/scheduler/doctor/trends/categories/platform?from=2025-04-18T23:21:37.620Z&to=2026-04-13T23:21:37.620Z", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/bbeffeb9-79ba-47cf-a996-513c422bc4c8?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/scheduler/doctor/trends/categories/security?from=2025-04-18T23:21:37.620Z&to=2026-04-13T23:21:37.620Z", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/263befd6-b2ee-4531-bd8e-7ff6b968b42b?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/263befd6-b2ee-4531-bd8e-7ff6b968b42b?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/context/preferences", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/263befd6-b2ee-4531-bd8e-7ff6b968b42b?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/platform/preferences/language", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/263befd6-b2ee-4531-bd8e-7ff6b968b42b?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/tips?route=/setup/integrations/263befd6-b2ee-4531-bd8e-7ff6b968b42b&locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/5c2d7215-ee04-4a8d-b213-03cd834ee799?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/platform/preferences/language", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/5c2d7215-ee04-4a8d-b213-03cd834ee799?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/release-orchestrator/releases/activity?outcome=failed&limit=0", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/5c2d7215-ee04-4a8d-b213-03cd834ee799?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/security/findings?severity=critical&disposition=unreviewed&limit=0", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/5c2d7215-ee04-4a8d-b213-03cd834ee799?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/context/regions", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/5c2d7215-ee04-4a8d-b213-03cd834ee799?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/release-orchestrator/releases/versions?gateStatus=block&limit=0", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/5c2d7215-ee04-4a8d-b213-03cd834ee799?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/tips?route=/setup/integrations/5c2d7215-ee04-4a8d-b213-03cd834ee799&locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/5c2d7215-ee04-4a8d-b213-03cd834ee799?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/5c2d7215-ee04-4a8d-b213-03cd834ee799?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/release-orchestrator/approvals?status=pending", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/efce990e-5381-41a0-8732-69756003fe91?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/tips?route=/setup/integrations/efce990e-5381-41a0-8732-69756003fe91&locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/efce990e-5381-41a0-8732-69756003fe91?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/scheduler/doctor/trends/categories/security?from=2025-04-18T23:21:46.189Z&to=2026-04-13T23:21:46.189Z", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/efce990e-5381-41a0-8732-69756003fe91?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/security/findings?severity=critical&disposition=unreviewed&limit=0", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/efce990e-5381-41a0-8732-69756003fe91?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/context/preferences", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/efce990e-5381-41a0-8732-69756003fe91?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/efce990e-5381-41a0-8732-69756003fe91?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/platform/preferences/language", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/efce990e-5381-41a0-8732-69756003fe91?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/scheduler/doctor/trends/categories/platform?from=2025-04-18T23:21:46.189Z&to=2026-04-13T23:21:46.189Z", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/5fafad2a-944c-4543-bcfe-fe60c303a744?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/security/findings?severity=critical&disposition=unreviewed&limit=0", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/5fafad2a-944c-4543-bcfe-fe60c303a744?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/5fafad2a-944c-4543-bcfe-fe60c303a744?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/tips?route=/setup/integrations/5fafad2a-944c-4543-bcfe-fe60c303a744&locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/5fafad2a-944c-4543-bcfe-fe60c303a744?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/platform/preferences/language", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/5fafad2a-944c-4543-bcfe-fe60c303a744?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/context/preferences", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/1cc18b24-c833-4a82-8447-d6c5cd130194?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/platform/preferences/language", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/1cc18b24-c833-4a82-8447-d6c5cd130194?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/security/findings?severity=critical&disposition=unreviewed&limit=0", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/1cc18b24-c833-4a82-8447-d6c5cd130194?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/tips?route=/setup/integrations/1cc18b24-c833-4a82-8447-d6c5cd130194&locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/1cc18b24-c833-4a82-8447-d6c5cd130194?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/1cc18b24-c833-4a82-8447-d6c5cd130194?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/context/regions", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/23cc3ac6-dbd2-4b3f-9690-0d0f089f76a0?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/context/regions", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/23cc3ac6-dbd2-4b3f-9690-0d0f089f76a0?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/security/findings?severity=critical&disposition=unreviewed&limit=0", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/23cc3ac6-dbd2-4b3f-9690-0d0f089f76a0?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/platform/preferences/language", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/23cc3ac6-dbd2-4b3f-9690-0d0f089f76a0?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/tips?route=/setup/integrations/23cc3ac6-dbd2-4b3f-9690-0d0f089f76a0&locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/23cc3ac6-dbd2-4b3f-9690-0d0f089f76a0?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/e6aa18c7-0bc8-4d67-83aa-63a64ffd7c2e?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/platform/preferences/language", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/e6aa18c7-0bc8-4d67-83aa-63a64ffd7c2e?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/scheduler/doctor/trends/categories/platform?from=2025-04-18T23:21:57.622Z&to=2026-04-13T23:21:57.622Z", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/e6aa18c7-0bc8-4d67-83aa-63a64ffd7c2e?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/release-orchestrator/releases/activity?outcome=failed&limit=0", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/e6aa18c7-0bc8-4d67-83aa-63a64ffd7c2e?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/security/findings?severity=critical&disposition=unreviewed&limit=0", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/e6aa18c7-0bc8-4d67-83aa-63a64ffd7c2e?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/e6aa18c7-0bc8-4d67-83aa-63a64ffd7c2e?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/context/preferences", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/e6aa18c7-0bc8-4d67-83aa-63a64ffd7c2e?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/tips?route=/setup/integrations/e6aa18c7-0bc8-4d67-83aa-63a64ffd7c2e&locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/e6aa18c7-0bc8-4d67-83aa-63a64ffd7c2e?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/scheduler/doctor/trends/categories/security?from=2025-04-18T23:21:57.622Z&to=2026-04-13T23:21:57.622Z", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/54844d7d-e209-494a-a81d-e8bff2e22f69?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/context/preferences", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/54844d7d-e209-494a-a81d-e8bff2e22f69?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/54844d7d-e209-494a-a81d-e8bff2e22f69?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/platform/preferences/language", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/54844d7d-e209-494a-a81d-e8bff2e22f69?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/tips?route=/setup/integrations/54844d7d-e209-494a-a81d-e8bff2e22f69&locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/c80ae6b1-d20a-410b-9f82-7bfe88ac0a99?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/security/findings?severity=critical&disposition=unreviewed&limit=0", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/c80ae6b1-d20a-410b-9f82-7bfe88ac0a99?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/c80ae6b1-d20a-410b-9f82-7bfe88ac0a99?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/tips?route=/setup/integrations/c80ae6b1-d20a-410b-9f82-7bfe88ac0a99&locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/c80ae6b1-d20a-410b-9f82-7bfe88ac0a99?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/platform/preferences/language", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/c80ae6b1-d20a-410b-9f82-7bfe88ac0a99?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/release-orchestrator/approvals?status=pending", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/c80ae6b1-d20a-410b-9f82-7bfe88ac0a99?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/release-orchestrator/releases/activity?outcome=failed&limit=0", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/c80ae6b1-d20a-410b-9f82-7bfe88ac0a99?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/context/regions", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/8634f246-ab4e-4db4-991b-9ef3f6fd8ca3?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/tips?route=/setup/integrations/8634f246-ab4e-4db4-991b-9ef3f6fd8ca3&locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/8634f246-ab4e-4db4-991b-9ef3f6fd8ca3?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/scheduler/doctor/trends/categories/platform?from=2025-04-18T23:22:06.150Z&to=2026-04-13T23:22:06.150Z", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/8634f246-ab4e-4db4-991b-9ef3f6fd8ca3?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/context/preferences", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/8634f246-ab4e-4db4-991b-9ef3f6fd8ca3?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/integrations/8634f246-ab4e-4db4-991b-9ef3f6fd8ca3", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/8634f246-ab4e-4db4-991b-9ef3f6fd8ca3?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/8634f246-ab4e-4db4-991b-9ef3f6fd8ca3?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/release-orchestrator/releases/activity?outcome=failed&limit=0", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/8634f246-ab4e-4db4-991b-9ef3f6fd8ca3?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/platform/preferences/language", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/afe36580-b1aa-4930-b81d-a1b800ee3d76?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/platform/preferences/language", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/afe36580-b1aa-4930-b81d-a1b800ee3d76?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/context/preferences", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/afe36580-b1aa-4930-b81d-a1b800ee3d76?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/afe36580-b1aa-4930-b81d-a1b800ee3d76?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/tips?route=/setup/integrations/afe36580-b1aa-4930-b81d-a1b800ee3d76&locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/f88b1704-62a5-46cf-8a82-278224de5ddc?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/release-orchestrator/releases/activity?outcome=failed&limit=0", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/f88b1704-62a5-46cf-8a82-278224de5ddc?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/context/preferences", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/f88b1704-62a5-46cf-8a82-278224de5ddc?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/tips?route=/setup/integrations/f88b1704-62a5-46cf-8a82-278224de5ddc&locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/f88b1704-62a5-46cf-8a82-278224de5ddc?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/platform/preferences/language", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/f88b1704-62a5-46cf-8a82-278224de5ddc?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/security/findings?severity=critical&disposition=unreviewed&limit=0", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/f88b1704-62a5-46cf-8a82-278224de5ddc?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/870ed598-e185-4740-b802-7239719aadeb?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/platform/preferences/language", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/870ed598-e185-4740-b802-7239719aadeb?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/scheduler/doctor/trends/categories/platform?from=2025-04-18T23:22:15.273Z&to=2026-04-13T23:22:15.273Z", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/870ed598-e185-4740-b802-7239719aadeb?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/870ed598-e185-4740-b802-7239719aadeb?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/context/preferences", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/870ed598-e185-4740-b802-7239719aadeb?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/release-orchestrator/releases/activity?outcome=failed&limit=0", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/870ed598-e185-4740-b802-7239719aadeb?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v2/security/findings?severity=critical&disposition=unreviewed&limit=0", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/870ed598-e185-4740-b802-7239719aadeb?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/tips?route=/setup/integrations/870ed598-e185-4740-b802-7239719aadeb&locale=en-US", + "error": "net::ERR_ABORTED" + }, + { + "page": "https://stella-ops.local/setup/integrations/870ed598-e185-4740-b802-7239719aadeb?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "method": "GET", + "url": "https://stella-ops.local/api/v1/scheduler/doctor/trends/categories/security?from=2025-04-18T23:22:15.273Z&to=2026-04-13T23:22:15.273Z", + "error": "net::ERR_ABORTED" + } + ], + "responseErrors": [] + }, + "lastUpdatedAtUtc": "2026-04-13T23:22:18.540Z", + "finalCatalog": { + "totalCount": 16, + "names": [ + "Local Consul", + "Local Docker Registry", + "Local eBPF Runtime Host", + "Local Gitea Server", + "Local GitHub App Fixture", + "Local GitLab CI", + "Local GitLab Container Registry", + "Local GitLab Server", + "Local Harbor Fixture", + "Local Jenkins", + "Local MinIO", + "Local Nexus Registry", + "Local NVD Mirror", + "Local OSV Mirror", + "Local StellaOps Mirror", + "Local Vault" + ] + }, + "failedIntegrationCount": 0, + "healthyIntegrationCount": 16, + "successfulTestCount": 16 +} diff --git a/src/Web/StellaOps.Web/output/playwright/live-integrations-ui-bootstrap.state.json b/src/Web/StellaOps.Web/output/playwright/live-integrations-ui-bootstrap.state.json new file mode 100644 index 000000000..7979904fd --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-integrations-ui-bootstrap.state.json @@ -0,0 +1,38 @@ +{ + "cookies": [], + "origins": [ + { + "origin": "https://stella-ops.local", + "localStorage": [ + { + "name": "stellaops.auth.session.full", + "value": "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyNDI5MCwiaWF0IjoxNzc2MTIyNDkwLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiOTU2ZjljNGUtNGVmMi00ODU0LTg0NTEtNTNiM2UwZTllMzc5Iiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMjI0OTAsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.SjscyX0IrOxirujiUezIVujTNN107P4A1SILVke6kF8sQPS3XC_0u3tIQKkEQzcDdmolLot-iR408Wm2uMIFKhZK4717tw3svwa48KsWSUoiW-fNErDjlPyVGVtzLmykdJsooqwBusoLJe2PwsJj0J3kkpT8YVJMm_AW-OEZxNfvTz_EM-I2ZVF32ErW4waWswbO_5CaNHziDNXlEsyT7eIEYVGvVY2UAV_Dr_VEXd-vvrXlf6t2onvXBpRr5bqsQOctCnV7aPkZqgew9GDPdeOtqr17l-uPs6O8KKKv5vTrj_YLNlBeM9DjmqYA6i07IWoOAx-GOtmV2a9KGXkQ-w\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.PGUaV_kPUQLr-BlrvYwSwQ7VZl5V_kUg8Yb3Q0RWjxvOcGjGIykdQvOrrTnfWk_U0EG-WWKY8HIjY7zGLVkMB4NkfFGN9-m7_JIDbvd50SBnYLeXC95HZPf0t0eJ45Prv5cvRTyt63EzHtHs_ttbp6ZLBQhqd_rmyop_q1AlKlfS8zcB45ZAlnpMBmiMpuQfxsOs9SzNvsbKvUF4UBq9VChgps4bCv3RDzOOpZbvhNTtA53af9nwoavqoB6utLqF5N7aXAC12XBMs2a2NVmdRMP3W4T-sZ1ksdhhKORbQdspXqu-PBzTuJ4Lq-HjWVZtQdO4T91I3fQb8zNXIScH7A.vk3i21BvJsqJvGklE3WW9Q.txCN69BgfMIdy9ghjTFQDEkgtI4VfJpz3-0oNNcePB_BeJqaaJryF_eNYXhUvFIz7SfRbCbjFPhS6wD_29YephOxZ6I9TyjpuncbVNila0ohV3eTiAzx6ZgVnJZmEUja3UU_nFTrJLZws2LXJU91SmGkq5-tQv4iPJMrIKkVTtUUOKbGT8gtTzQaSPAoU0rLk7vfmDKIKGm9yO-TKcgXCxny2odkSn87bfENLIaLC5uYbtVxbJEY_2oT0_ytuMEurnKcsgjv1FaVFLg7t2I1LgNIlKVfvCfMh1Q4k7wtitQhy_DAzgoo522-j4RWRqhvRrjAxG-PCVXHAqZlMakL81XCLdX2oMLgr4Aba_9g-APvG-gVvjOcNQzUuVBw5ThD3ESJEXeS-w3V0cZm66hSMQ5SjWmXo1fbpGD8V8wYb5UlOZvo1ZLEV3f4ao2F0GLhAHD2cB-VwX-SatfBOPvPRBgvECGI9fBG9qGn3gQ_RK7rh-HhH9tEsW5uCaphZpjTCvUVgJmUMQztXbS6yCfmQqQa0AL3y9fWQbtn121xbbduHS8R_0z-fNMfkS3HlI8AG7IBkYXyohezkhGT6HlIfKzpFBWQKmNKioe6HA-h5XZMLVtGABrKJmUm3omhS1i3rAFOZ4H3TlLpjnv3aVjZONSA2KlJ6UnAIwo8x3j_T4WHtKfxD-e24K_5rhAkhYql6vXZAhaQxz9NZoubrxeQgr7pJRj9xJmd63fricLcWDV56cMwQXYgNiQZ_kz3-uUKdS6pGqKCvnj2XSalpTjGzmAVol5kbNCzN7RysJlJUgbPunKOvwEoAZ3Dc1KDp056a6Ufw9NSp43j8YDF0hOW6oMasciFXCZnkbmlHeeH0WZs2q1dAWNFPP5c_avAoZZmNfBTbDrOsI75IvfX5QV2BDozwv7lIe3kBVeVeytHPn8DJtZc07aEpjFsItD0y4eko3MGGHt7GSDABpsuO3SsKIYNyZKLlCL1a90TbTRtoq473bZFKkCzKuKEFPZzWahp4D1gi19tRGlybpoaR0RfOHRT9ejF9heWbqykC7WrB2VsqIYzxm5GecjKL9JMlzC4u7cX8jRDu1MJcux0hEc1Vltztj7aFklgxRwK-2lA65T_X1dtF3WDG1UzuU_B4IKzRTr4Il39W7bdKKlrshp8zgmmYxXEvHZTUmVBNUU9V9haEXfYT92vcHZtDD8NNoKa2-asNI7jBFLOFbyLXXsed8HC6lLl8CU6DzO27TntztthxNxhSv2yzH6-TMv5fNtt_fZlP7ID1RjpqwxUqn9K8mGP6kyKfg5MfbytCQi6dFJqNgQbequExareeCb4G2cyP2vOYnzSyQrTnRnDsHqXiyANZzJbJXdI0FoVKuLUU8AlmCsCFWr35LrUlf_SyQdmV6jp-BFUV9gv5N5y89oragfI6SH6gacHG_c77VHegfpJMV309_h_srsmARpcWrA_Y9daO_VJjGPe0qos652xW7hs2qn_orD2O4VdbNgdP_KmVla0PzeTcx7pGIUlAFmD_xSDc52AMDmwk3cX_n4RxdHzGvyAJasRUKR2lfqRKLV5JHkFOUkGR5xQPgfEep68-mhnHRaBw3kE0kzGdBni5lpT8tBa3IK7ShuWp81B09cPKEbsGxqB9LPoff4sXRBF3vZKjvkx1lfyYKARtY1A1FNj3iQNvi8gFI3gy9fzSttpz4X1khh0S_mR6ou6r-aksCCK5TGx3gt_n9tXFXNJZ79wtsTlYU8V5AesRrEs6qKGvo2usx8um2P7OqrC_iwMqgF2YtUZe-OrLV_J5d6RrVXQGN9D6YMDZsJ0Dxo--ff7BgglXVjCKChdzA1Fzg6sLOKnL5SEobrC8SFDLMStK23QM-71b4VB2jhLVAV4HdErT6QpH1QIUhtQZtnMDFgwNXC0hemBIxeQjFc6q18K9Hv_c2TjoJ4QipIQI_9tGSE-0-VP7FCIlHEe3ONK7mihvx1ACYiWzd84xj21Wxi0aS-bAmvz9qJykLr9ct-O2bnP6HDdkquweCgxQ_pHsUIAWE87KkTboXXTSvAcBb9Mr7NI8wLHbrSJ3LCUtFg_RyGdEFW3B4gp-NuC-YZfM8X9iUvkqal80Fxe8onqWAvWtVnyfLBCxECgdiZgLgOvODBLHJUiFK5qcE4KgK--XOj9qs_yiUkuXrw7P43rCu1WpmoxdnvULGlfDvZg3O-AiB1ncDuz1YqxjMnMRBl5P01lQur-6VHRMTav4cxpbXiKdc2nw_R1ix_R7q2mefmXlKKRa3MiZiZFrdeTtexclWIFKMzBl6YGl7fPJccCyqw7YBBOBVj1Az6-KkLYxlATgErBYcfq93TYLpgV5Q8-8nFjTmNddcfIWLj3D8jRoT0E4PlzbfUnDWJaxQlrzkUdoq_SIIvBmRLT3n439_xjn7aTlfGY8TtAb4Ev8NKsBwXRd1IzdS2f3EMS2NHazDYMjhITFg92IqyL9w88qlpV90EqvzmeDvpKnFPlYzeUf8fy0IHHiD-oeKOGpXNrnE8Uh-fYUWMHMVcIKQ7Ag5VqmdJGuz3StHzva-SXa46pPrcx9n9Eso9qd72Jx38bZoYWKz4kfB1wSinEl6JTzJTOPCzHxJFSKYhqlCvuMvIDtvyRrOVhaN8z-h1V4OLZN3og3TtK6Ln6I40AXZjByK1naRG9yK_lJlzOGXkTlj_4vkpqazdbiDQBawIGNNJi8T7ZrzF8rvfnGOrsdNn5V833H53hufWSSnuFMOyWwQlxDKaPEBz0DYt2wW8cCxARG5NGQdyUw744ic9bfMS5zaGrGYZk-znteQP8k0OSeDEg49lGhFpeipkCWJkhUFVxfu0nv6H06PwlP9RdxBEkYVS_1D-P7Xow4fj47C3o5Scpgw4eRsnXu0jvp3fPBYTtaeCYYpCeri4EqVeYF3bVK0x04A7_asi2CGRd7Bc-1CYgeJ-gdB8Rh58u5Q6rLHs5D6ZHlyrtZH2bu_rZxMSETXf4bJBBI8umOUdzBWIv2P_Ww_uUVyCppvMdNeGDt8IZKM9CkrYk_xDguUH7AN-bZFHNt82idPTDVaD6BMeOnoqsvLhY22p3dzOp-oTqpdXTdq31lWgxo3xC4UbOLdESz0G1vBuRVoYnbh0zw5RTQrQRWXmeTBu81qAbM_hxrbsGCAF0zBQmaJqAmuxsAGoGTs1etz9_0VG6qX-DBFlpgoHTP1VA_tXbJTO3r52cTyaheX4xfZ8f19hzGu56umAh0cIxzKvdJetskCn8vFmJBEGicqIJu5oxEe_p23GLFQd8HSdG2MbmPd8OBuSiEeDUvmVwfmbkfQkODNGheGL6a-d9C_b6a-6LXpFI8erjxs2ruDINAkmd15OLOjUHzY66aTSuPuGlDLRwBuycQAvwuIjQb7hTfwxjoZGXhc_IsMhpJoj5zAOzYTE7gf_Dg-u1pmpXd0x6ySWv4Ms1yC-voilS8sdCoVNEmudKAJXY1cd29X2ILAQ09fq3QEgrn2FB3eEDqwCFvwjgJpFvweZcWXcb6btHLKyoJjYtfb8ROMOCkVZQtRx5cPGfM0chEjXYnBUxMsBtG408ou5QeDbAJkpCeI42CeFRm0GEb_v6gxzWgZAlqYswk4A0v0htfgRn8c6JxcREROgRNcfDSBA9JAEFLCcIoAPIPbYLhRY1AREAhNujESfzJJ5por3nepT_6t5L4YnhFOMrOLryGu-dvM-lcbtQmwlQIi5Vaky8VPai4ljETuLgtjkBxabf38YcnnEwrThff4mwIKIyS95FacBTPxOFTc9PoNxL8DsLm7HW93tHu2xKOe-zo19DJxjcRaWZ2xwPUNAHA1RWT2TCL4QE3amGxP3k4xmPCy2noUeqb2dfNIqLAOHOSMdZ97nlOqbuQB7RxsTo7f9hiM6PwqkLf8uZdHWHsix7y6RpA_Yiz8SDvLXURbrEVQmrD4_riwIjpJroLgx9H4mDLZlgb5Dho8eNZLMBL2mbrzcTpa9rsG0jsYizjIjdpVpo-z4_5tZKDkPN2eLmpe8K_h8cLHQomwyHELEg_6r6Z5C_T8zq1DIcNAOnu3aSv91jL8rcSa4LkIloDRxRVApVClx1VX56cghwFcF_Xemf-o57aCbxKJxnFDMzCXFgdsLSWds4GOYkbL1pDpw7Mu_nMx0148VHyW3dhMTPOYeRhH__cGB85WS49RnG2gTbClCVKlVql4ZwR7hYaYMDuJeYXEdYRxbxly9CIJB2DSvcvdUFONJu3QqD4HBpVM2v2Qnkv2BFTAHSW0hHqcqndnoOHlhliCe27ll_RtGxWzOObGmMmtgRewIsDc00N5MOH7PTcbzq0bzj6NQlZ9pcJs-Gz04sqf1iov-PD6qsSzf2z6qnjSs-Ejlj_B5Pfmt8ynTwFbAxD34kadh4M8mOX-_zHgnmfiqcgAzngrcETD2_OgJhVKg4I3huGD-IBXc177j-EANfAIc_vz12MOe3lcKnr5h9QYL_wlTx7oFWlMUsUHwUYLmgP1cJjzaHyXGdp1sfdmV1WjhxXKL9kEPMIlFN6igBHCjqE4gz0fLFxDyXOu5G7ROkCB87VzKGqTJnbneJ6vBgKBRgDaPgU4so1pIcuVsrmq42ta8mctKJfsR0o99JxxWiiExsux9g_XXz4XCoQ9LYD_Ul1Dz4TLDbp43xifXYjygSSjvZTj7OjUNT75NdU3JP02H0HqjxwwdGYy5tsojN2HJJdNM0i9XvcjP98OIjXd4wc2E5xg.QDXvkU35n-U0snZ_h9GKSo1Q_3HzVhL44pDeULM9-Uc\",\"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\":1776124289299},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyNTc5MCwiaWF0IjoxNzc2MTIyNDkwLCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiI2MzViNjJhZi05NmI1LTQzZjMtOWIxZC01NDVkNWMwYjcxZDEiLCJhdF9oYXNoIjoiaDJHRlFiU0NtM1pHMk5STGgtS2hJZyJ9.GmouLQf3mjoAXANjyjPKiK3vMM4nIc14V7p-WKDDnaLfOABPqNDRg_4nbCTaJ_ILgQcFkX_lm-GMlo9g6ibLbEnq8Stxs15DamLsf4SdGFL63o7UGqGIiqA_maVCMkLly1Y6RQrgijqEFlVL4vLFOM--qt9AHoHMJD7TXjjnMwcY7ID-61SLx-bcbjrxcGix9ISOmH74DMYQaI3wuY_pwre9EaxuaX2jI2kEx_T3G9_BaJhmObMVPB1JAbjPYzJU-vvy2KFXSGiR-NrZY62rP-wdjRfPf6SSSYgoss8uqwl7NymIzxPBI95mx2Qkley_zQGVgp2unhUXL2yQL605lw\"},\"dpopKeyThumbprint\":\"EBzFLNz4pOAbecSIIxZqr-fm0NVvCkAGAwKQsnsNoKk\",\"issuedAtEpochMs\":1776122490300,\"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\":1776122490000,\"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}" + }, + { + "name": "stellaops.theme", + "value": "system" + }, + { + "name": "stellaops.auth.session.info", + "value": "{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"expiresAtEpochMs\":1776124289299,\"issuedAtEpochMs\":1776122490300,\"dpopKeyThumbprint\":\"EBzFLNz4pOAbecSIIxZqr-fm0NVvCkAGAwKQsnsNoKk\",\"tenantId\":\"demo-prod\"}" + }, + { + "name": "stellaops.sidebar.preferences", + "value": "{\"sidebarCollapsed\":false,\"collapsedGroups\":[\"evidence\",\"setup-admin\"],\"collapsedSections\":[]}" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/Web/StellaOps.Web/output/playwright/live-release-deployments-proof.auth.json b/src/Web/StellaOps.Web/output/playwright/live-release-deployments-proof.auth.json new file mode 100644 index 000000000..3ce8225f0 --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-release-deployments-proof.auth.json @@ -0,0 +1,55 @@ +{ + "authenticatedAtUtc": "2026-04-13T23:37:21.636Z", + "baseUrl": "https://stella-ops.local", + "finalUrl": "https://stella-ops.local/?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Dashboard - StellaOps", + "cookies": [], + "storage": { + "localStorageEntries": [ + [ + "stellaops.auth.session.full", + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyNTIzOSwiaWF0IjoxNzc2MTIzNDM5LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiN2UxMDU4MmEtYjZlZi00ZmNjLWFlMTktM2Q4YzZhMDNmZTkxIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMjM0MzksIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.lwYmIBDfA5a43p3EqLuaR2LRkPkL1fSNLWfFA4WgUrhu9uTuOLpoNnQDcp7S8ZSkA8xZ9R0bIiHoDk3qbuYtYOGr7t0gVwd9L97QLxiuPdiD729V_UAF6-aDBhsdFTypsDSrKGxMuDEQ_GLkWpraIAXEhtb01czZkMA4guV7KsGvj4PZOOGVm7CGe_RSDzy2XzcGy29GoHMqa9ausr4kQJTamDGvnVF_n6CRtjBfZepY_uQEtxPMS6xPjR9lXEDf2PwP6CfdBfJXnkA7t_PsnspTnZM0CjJm2fyKAIbCvrOXT47e6d54vZwPPD2PSLAPTeUFuXk9NJTuWFs837P6yg\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.yZg2g96CVWD3R9d-PfDNSugVayYXjeJDrFpC46axzRQOdPlaVZw_XcyOeALIyAIqDSvgjx6g875xjMcjeJnNsyBL2uyzqyf9ZE_CcLJwPgHsjCNp8xnEJg5hkS8taXdzMTB2B3aaVN4wjxYXrTXx9sxBmwsKtTtlNKA6UZ9T8PHMCyOH683quLVipNU-Yy-mZ2e21uKfk81E3ANG4puS987ZQMBO4Ubq_xaKn28FoLq-CqLtw9SnLdc7UM01m9CoxEpjFCG5Xc_DhbTKJWe-6gdOmmK8F5QUOmclOjLoPuAEC8coQm4FFayKOAkHnUDLNs-LiLrCmKhIYZ3Q_OD67w.0K4Ny0kXAkTmAfiqDf0ZlA.6ytX07n70GW1qjnEVkbPg8mdzsanAILxyT3PJ2UVLMlH7zlBVw37kz0DpYV-4gKV2jhsWZ7pCjtRmCUXkNi-lOqR4ebzHvPghtZuBYf__CipUDtlgd6HclNlVCZzAnz2-76JA-J08ldH6-8Ana-ljYxeqc2AXmFAaLmYYGOaFAU76DVnypDp17bjPzJ0pEf3MXvgQWcEBdDe98pCB_VkY5yHkHeM8WG2DCNtyQrpOmVzqJQ-8WK9HugeP87RLdEmbZsZshKkPv1CPl_KYAzmSRj8BeYQmQ70ciqzHn2zWDSj8UHm4vPis9WiufO5zLzTBrIS5t6pwRd3k3GP8YiPOALOJNNXXZWglrN6Tq72DJ7O5j9Hk6MSh0HohfpO3KsicO65UKsu62vXn_I7qZne2yOxg_-nwDav69BJNUZT26QeIDIOJETpFCuKRPBFe058QeQaMAgP-lTtif4DwFgLba519M_4-16YcoH6pXS06Qs5LCIQE4gIEhC1CvsQxA46P7vrjQwEnZVP1f-AjYWFthSlrXrjM8F9JXRg0S4dhYKXZPylOv8k02hOZ28X6tZE3qHXni9v05WDqsPflg0ih3nr2fS7-YJjKrNLllSs8-eDVczjtZeaWEXq-VLHQHmfqQdF3jmVS-MCpjOu13B0C3Hrq7RUWVOmJkQjk7aopcECi7IksmkzpA4EbIcoszsEXHqE_Ixe44mcgIrXDkaLcgnu2F_iDW92qrCjacWWNFeMI5oohlSSL2uKqP5xghvnhvEbbZZ833O_qUqtgovTWOsYnf8fBo1rGhRmwdYHPEDkdTfVMz10zmp3PjhO69z6daSbdDk0Nmi1Qqqdkn6iFec_faXBpwu86GmB3beqySF8c8EDsmAzY7PwIh0O9ioxeUJt4eGuM7ZhqYuLI-LzadqwT7NRZSytxgAChtRV1t1G1X2vrYJ20XOuC6c9_j4Uj11mrOb76g_AHnOg2W6Zkrzv3NCORdmDpHeeqMfIrBhYAG359Szz-QRErJO6LyexUUp5in-n7BwfjFJhosDXduFponKWJiErF1YDPObVRuk6zzrWvuSPO2Wg9PxTrZdnDkgkwmwwvad2VS_TZHgTReXRCb2v5PgnhEWC9_YH2NJbLOHA9c49PdeQE2dcuvAJjMrsZHHVOJ-d0a4eHDPKW9CatJQTfpoJE1TsXWsNyvpwxQhpO2jKByhFY1NRk_s2GI5oEByaxzUCRR5VpNzmXGArKisAMlMPibTls0oKjyFyicOyf0iVILKAaV23gZTir0v_p8x3kqSBaUzItid_Ul5TrEWvU3BTde30OOKZXe2cP0OslJMrAp7cdeEBlwlOtdfnT1GtpLQ4hhk2CMmX4T66-3fs-f8oEx7jBT44QFFXHGbvGN2mOqceq8NmD32Z1eruGjY4ugWUPrFuilT6CMsc9XfhACMIEgNRvQNn9zROUiBKaXgUchqU48iKK1xfeD0X9R1599gg3pAHvstOpf6mUpOKBMGfR6QGmeuIXX28arnF4jpEDPuOVKBBl1UGaqL3WnXcKJpmEZqG_s5eH5TYCVKuzn7fgjYmUT1De9zOe_bl4dloHCNYdtpZNkuANX7xbA0q45ZV2tcWLSrH27FBU8kKBOWKKDmYF9Aau7Irlxu8jUybJs5hOsi9--DbUYWXsXBYfhto_s7sq5_pDLp3yhpfIw25l9m79fnBBWexzHUUIfUiidjzvmFk9vfaHR_NQl6WdLV9NN3jm-n-Sa1NhRou8V6eHOUKxZltqjG3Fm_A26MTJzXqw50PMKkq5VHe55FXf3R0eZWkqLgePI_xwreWbyufVuN92xarTOwt-MVsN_xOG6vtrcW20ofaMhSf8LHBg2IodK44bGJKjsN2DRWigHNGXNA5AKjRkgCGMB29-zau3P2EQ6DyxjtCQcvdfDjlKoL40bOPwofgSSukD3gTT0eN1VMGFn6cFC1Igo_2JBTUPN2Lmp0l8ubDEBkFNSnKg9b-UlpokN23V7Mhpzeibv07JgCxP-UlNm9XYo2qk6Ph_eT-gVPiCRbeWoi9qgELL_WK8stQaDXz6IYDq3rCscne7LHU5Y_yIhuVEsxsfcTtDDkq3tULgkFZ9wd9oQnKubJRlhL3BVBOAmzgUjNvSSuD89FzKAFo4K8FrzxUmOqXDyI1jGsesKrnoeBzI3MNXXm_Ff9oK7g3QjrwZ4V9uOoDvRxLNU1-DxiZHT2TPPEyOxuetqzV-gLqg6EDmRELGMpkHv6D1Kryx46URrwIeGRPwUt8X0rmbMHjwWmifrHPTlzcLsZ7EIajgiqF-HRMxZdMntoQFBb9WWLu9IBM1s7cVkLM97wbszFvUkTn8ChfdBkNnwjVwFeg8mDWRwDqfpaJ6YpWvzF_yz1IK-Qt9IOEqjcav_b9Oy5np3PYRLC1WYP9MWo9-Cnp6nN7MjrV-HJnsR5sh2VXUJNIFK19BEm1_11DXidw2b4uMe3TXjELK52k5g4lIrdOQnS87udUqhc1szfzjaWULjF2FwRCERewgJ6zg7wxymjMenyu5YDlWga2tPUCJmEA8vFLZjsr9hnpekDSa_Wu25OdbSsjKNg9aQJzBzpX5upZrOE4nJvG7-bTyUde7sHF4yqNxD_UbOPVkjcNpUBfNJtseqwnXdOu1EAMC5GuHmW78EQh7ZId7x7pnw8mUjd7l1Mn4TK3I645fYpk1OP3z5VDFfpncwC2-YF9mpJUIYp3-LhXoS61y7bZp2f9PXvttGR8QVYgh9fxirSnULgHf4EmPUkgCfwcBcYVTqpN0l7beXb1uWNMqs2WrTSUofZP7HAKCtI8UwsRvakxC_sYXAQjQmOVhxipsjoNuaZO6Twr4RnaQJsEpKUQxDiuHQnhqsNepIGsYar5AoIpFHezof1r52ADaYbJuY4qLXEzJSzJl-KmYJGpyPwFWX3ymE25wFJKUli0M9j4Z_s2FX_PewL8WiLux6pZ61Q04MTGgX7UeimEFJcxXnVYJuwYPzRnK6Wv9fTo-CTLszdVQrH4wz4SofMXluZyF_56C_gbK_XuJI2LoXNxqN1KaIgQQtOgrM80dHrqUby6L8C2KCl2IUhytjP3-zmRsbEmwWzdCOqGl-jXkaxbd9QpdUj_XkgmZjZG6EA4eKVJrpfKwBceAff6s3sUNHgDSdGwayI4OhW9Hq7Y24HCNwZ7g7Qz2ifLdLdAhblFOGKP5cPAhQZ-iFgog6YjzDHTRm6b-R8Rr01-Ac4WbE0XMF-dcdY0gaqEUdsJNahpQheZ8zxGmAQoYJjr6O4t0TAUVVZs2_8Bb-BmJouzBAgBKePAoHohQ0_AtHkm2A12cYDWSOXArKK2n6vkBnTTbuA4aU9QrON_ENxx9nM6VDRGvQ5zzOnQ_9sU6OwCCWY1b8ghOOOvX-FlUJ49X1X5s1irGhnE7Ou-IVXAFO5cq3pd2DhfsuPei9poW3niyJOFcu9E56vw70ygJEQzwf2sfs2DCJ0Tit7gXGhCcsi32i7_oNV8lj1e2F4CnscXjR8CXVxhJtuYdhvSABLLFq1P_IuWBkpdSxsw-ul2RHekvf08yJcrlxUd8Xb7KvJNpDds74dbGM1jubGFSEgdi0c45KWmz4OnNH2Ua-6rZ12GpR0HwkBaWy4eeyNCl6oyVyjGQRUJMQ4KuzjAGq6MImb8m-2-9n0_KOFYFFZklIydyEhyhRecJ7rXTKyYwjGqcML9l6sffUi5f5HXUA5vLqoYi8sfnY3xZ5q4YeAcY8cRdKShlCjt0ln1kwuRC440EuNJWUPMrNPppWKjfaz-hRtxhDk4hxiwKCbddY74eOwpunkbplrmqHJPzZzeW7KgeKkd_HfoTymWI442bto8rS041nlXLcHc2cilOXpF7zyu6s3q_C5u_oRELTyXTZst5lQwtYNb-K-8V9oVnO_bfW6inmmJAOBa-2Es32lCkf3FEGHocawaXgpT9ZHEyU-izRBz4SWgRZAJab8qBs1QgnNxv0ZGtiJPtMtwkzHRv4jy0cCH6VGYjmN7m2GLJbRjVe3QkVBHYhJnCsDNO92R7Ql3jv3mfd97w6_9wt42QVItM2eY28Rx-M9MhxhAjl6q00TrzLJ4xW_AWB0X_XgHvIld66KOs2UiSVgxp2SGfkg2WeJPpPxuAo-D6vpEkUvnaDMSZm1ZSsqqi0njeFTz8PASxLFOwq7MQptisFxDqjTboE99qxEBDqFkA3ajO2M99MHdRg2FfhChhnEJArf687zLHm-K95GLMisKXRB1Mi5EB4YLtkhh2v_n3p_K9jZmg4b1qT3Y2GEYY589GVgPZliszVxgdahhOZkdyzOEqY9I0ggHZnPncUXmzW4VJ4zbO-fJU1iF6coMr3dsv_hRxkr1h6jLrgwN0uKSRXGIQNSWBPRtwdSTLm-yFHs7S1LOzd1yZiyuWrsl947_w4qRkSyAyb2koePid0HfVcIOL_Mvujy1sf3MuYvpbY1VqKWQXlpe6zdJ-SH4GjdV9YlNhM_XuUzAl1sS09WJlwN3gV0EojRLCpl_r4yMHCGeROIndBZdereYCIC96VNjGANzt3pMS_Th7oKm9ABcCILvJre4WiooIi-24cPgI7Bbz8zSpR_zplhJAxkaqXcNYHFaGZHkjnNbZlPari1rc5txph2BAotmxuqJpLfcWK2SPGWCm0gCMyd-tgmurYaJs9Kl7jbJQNap3ccsG37Oar1sWHdx0TtvbyhxiNXDzdIPCLDq6rJH4tb7pyq_KnBRgw.zMEYVCFScKhxzjLgWVWIMgIaVzuODtdgztbNz_FrBHE\",\"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\":1776125238990},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyNjczOSwiaWF0IjoxNzc2MTIzNDM5LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiI4NDk2Yzk2NS1iNmRlLTRiODgtODg3My01NTYyYWVlNjkzZGIiLCJhdF9oYXNoIjoiYVotX1c0MTUtT2hfcFl2ckFZeEd2QSJ9.VjYrPdj0URFlku7-ePrqNzeX6UqDSROGNnS5_X7Qf0ZqH2S8z6B7jCIEAfz7AQdrH2to58SiCX4lXKf5U9o-qPYuK0AxNPDyo1PeZWQaka13teIm-lVqIiCPE8cHr99vkLaWviAfCxxKDmakdpgThbEo74AKoKQ_u-RVInKScU21Vm_zuXTvmn43szlN0OFydMmvReibB1hSNtEUPNzxbGpC3JkJOUbHSzVVpM9gwJHDJtJERz1GZ5Entbb8micW0ik6ea_FuYmonD4mnA0rluPE7tFk7ij7E36wawjY_zhcV4Du89WD-KwLNEzbtZnHjOzIXuSqq-UXcTW1e6gZrg\"},\"dpopKeyThumbprint\":\"CBxwIIV_loH56FxGGBH2hpXhwGnIiOhlucB5KXMdPMA\",\"issuedAtEpochMs\":1776123438991,\"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\":1776123439000,\"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}" + ], + [ + "stellaops.theme", + "system" + ], + [ + "stellaops.auth.session.info", + "{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"expiresAtEpochMs\":1776125238990,\"issuedAtEpochMs\":1776123438991,\"dpopKeyThumbprint\":\"CBxwIIV_loH56FxGGBH2hpXhwGnIiOhlucB5KXMdPMA\",\"tenantId\":\"demo-prod\"}" + ], + [ + "stellaops.sidebar.preferences", + "{\"sidebarCollapsed\":false,\"collapsedGroups\":[\"evidence\",\"setup-admin\"],\"collapsedSections\":[]}" + ] + ], + "sessionStorageEntries": [ + [ + "stellaops.auth.session.full", + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyNTIzOSwiaWF0IjoxNzc2MTIzNDM5LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiN2UxMDU4MmEtYjZlZi00ZmNjLWFlMTktM2Q4YzZhMDNmZTkxIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMjM0MzksIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.lwYmIBDfA5a43p3EqLuaR2LRkPkL1fSNLWfFA4WgUrhu9uTuOLpoNnQDcp7S8ZSkA8xZ9R0bIiHoDk3qbuYtYOGr7t0gVwd9L97QLxiuPdiD729V_UAF6-aDBhsdFTypsDSrKGxMuDEQ_GLkWpraIAXEhtb01czZkMA4guV7KsGvj4PZOOGVm7CGe_RSDzy2XzcGy29GoHMqa9ausr4kQJTamDGvnVF_n6CRtjBfZepY_uQEtxPMS6xPjR9lXEDf2PwP6CfdBfJXnkA7t_PsnspTnZM0CjJm2fyKAIbCvrOXT47e6d54vZwPPD2PSLAPTeUFuXk9NJTuWFs837P6yg\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.yZg2g96CVWD3R9d-PfDNSugVayYXjeJDrFpC46axzRQOdPlaVZw_XcyOeALIyAIqDSvgjx6g875xjMcjeJnNsyBL2uyzqyf9ZE_CcLJwPgHsjCNp8xnEJg5hkS8taXdzMTB2B3aaVN4wjxYXrTXx9sxBmwsKtTtlNKA6UZ9T8PHMCyOH683quLVipNU-Yy-mZ2e21uKfk81E3ANG4puS987ZQMBO4Ubq_xaKn28FoLq-CqLtw9SnLdc7UM01m9CoxEpjFCG5Xc_DhbTKJWe-6gdOmmK8F5QUOmclOjLoPuAEC8coQm4FFayKOAkHnUDLNs-LiLrCmKhIYZ3Q_OD67w.0K4Ny0kXAkTmAfiqDf0ZlA.6ytX07n70GW1qjnEVkbPg8mdzsanAILxyT3PJ2UVLMlH7zlBVw37kz0DpYV-4gKV2jhsWZ7pCjtRmCUXkNi-lOqR4ebzHvPghtZuBYf__CipUDtlgd6HclNlVCZzAnz2-76JA-J08ldH6-8Ana-ljYxeqc2AXmFAaLmYYGOaFAU76DVnypDp17bjPzJ0pEf3MXvgQWcEBdDe98pCB_VkY5yHkHeM8WG2DCNtyQrpOmVzqJQ-8WK9HugeP87RLdEmbZsZshKkPv1CPl_KYAzmSRj8BeYQmQ70ciqzHn2zWDSj8UHm4vPis9WiufO5zLzTBrIS5t6pwRd3k3GP8YiPOALOJNNXXZWglrN6Tq72DJ7O5j9Hk6MSh0HohfpO3KsicO65UKsu62vXn_I7qZne2yOxg_-nwDav69BJNUZT26QeIDIOJETpFCuKRPBFe058QeQaMAgP-lTtif4DwFgLba519M_4-16YcoH6pXS06Qs5LCIQE4gIEhC1CvsQxA46P7vrjQwEnZVP1f-AjYWFthSlrXrjM8F9JXRg0S4dhYKXZPylOv8k02hOZ28X6tZE3qHXni9v05WDqsPflg0ih3nr2fS7-YJjKrNLllSs8-eDVczjtZeaWEXq-VLHQHmfqQdF3jmVS-MCpjOu13B0C3Hrq7RUWVOmJkQjk7aopcECi7IksmkzpA4EbIcoszsEXHqE_Ixe44mcgIrXDkaLcgnu2F_iDW92qrCjacWWNFeMI5oohlSSL2uKqP5xghvnhvEbbZZ833O_qUqtgovTWOsYnf8fBo1rGhRmwdYHPEDkdTfVMz10zmp3PjhO69z6daSbdDk0Nmi1Qqqdkn6iFec_faXBpwu86GmB3beqySF8c8EDsmAzY7PwIh0O9ioxeUJt4eGuM7ZhqYuLI-LzadqwT7NRZSytxgAChtRV1t1G1X2vrYJ20XOuC6c9_j4Uj11mrOb76g_AHnOg2W6Zkrzv3NCORdmDpHeeqMfIrBhYAG359Szz-QRErJO6LyexUUp5in-n7BwfjFJhosDXduFponKWJiErF1YDPObVRuk6zzrWvuSPO2Wg9PxTrZdnDkgkwmwwvad2VS_TZHgTReXRCb2v5PgnhEWC9_YH2NJbLOHA9c49PdeQE2dcuvAJjMrsZHHVOJ-d0a4eHDPKW9CatJQTfpoJE1TsXWsNyvpwxQhpO2jKByhFY1NRk_s2GI5oEByaxzUCRR5VpNzmXGArKisAMlMPibTls0oKjyFyicOyf0iVILKAaV23gZTir0v_p8x3kqSBaUzItid_Ul5TrEWvU3BTde30OOKZXe2cP0OslJMrAp7cdeEBlwlOtdfnT1GtpLQ4hhk2CMmX4T66-3fs-f8oEx7jBT44QFFXHGbvGN2mOqceq8NmD32Z1eruGjY4ugWUPrFuilT6CMsc9XfhACMIEgNRvQNn9zROUiBKaXgUchqU48iKK1xfeD0X9R1599gg3pAHvstOpf6mUpOKBMGfR6QGmeuIXX28arnF4jpEDPuOVKBBl1UGaqL3WnXcKJpmEZqG_s5eH5TYCVKuzn7fgjYmUT1De9zOe_bl4dloHCNYdtpZNkuANX7xbA0q45ZV2tcWLSrH27FBU8kKBOWKKDmYF9Aau7Irlxu8jUybJs5hOsi9--DbUYWXsXBYfhto_s7sq5_pDLp3yhpfIw25l9m79fnBBWexzHUUIfUiidjzvmFk9vfaHR_NQl6WdLV9NN3jm-n-Sa1NhRou8V6eHOUKxZltqjG3Fm_A26MTJzXqw50PMKkq5VHe55FXf3R0eZWkqLgePI_xwreWbyufVuN92xarTOwt-MVsN_xOG6vtrcW20ofaMhSf8LHBg2IodK44bGJKjsN2DRWigHNGXNA5AKjRkgCGMB29-zau3P2EQ6DyxjtCQcvdfDjlKoL40bOPwofgSSukD3gTT0eN1VMGFn6cFC1Igo_2JBTUPN2Lmp0l8ubDEBkFNSnKg9b-UlpokN23V7Mhpzeibv07JgCxP-UlNm9XYo2qk6Ph_eT-gVPiCRbeWoi9qgELL_WK8stQaDXz6IYDq3rCscne7LHU5Y_yIhuVEsxsfcTtDDkq3tULgkFZ9wd9oQnKubJRlhL3BVBOAmzgUjNvSSuD89FzKAFo4K8FrzxUmOqXDyI1jGsesKrnoeBzI3MNXXm_Ff9oK7g3QjrwZ4V9uOoDvRxLNU1-DxiZHT2TPPEyOxuetqzV-gLqg6EDmRELGMpkHv6D1Kryx46URrwIeGRPwUt8X0rmbMHjwWmifrHPTlzcLsZ7EIajgiqF-HRMxZdMntoQFBb9WWLu9IBM1s7cVkLM97wbszFvUkTn8ChfdBkNnwjVwFeg8mDWRwDqfpaJ6YpWvzF_yz1IK-Qt9IOEqjcav_b9Oy5np3PYRLC1WYP9MWo9-Cnp6nN7MjrV-HJnsR5sh2VXUJNIFK19BEm1_11DXidw2b4uMe3TXjELK52k5g4lIrdOQnS87udUqhc1szfzjaWULjF2FwRCERewgJ6zg7wxymjMenyu5YDlWga2tPUCJmEA8vFLZjsr9hnpekDSa_Wu25OdbSsjKNg9aQJzBzpX5upZrOE4nJvG7-bTyUde7sHF4yqNxD_UbOPVkjcNpUBfNJtseqwnXdOu1EAMC5GuHmW78EQh7ZId7x7pnw8mUjd7l1Mn4TK3I645fYpk1OP3z5VDFfpncwC2-YF9mpJUIYp3-LhXoS61y7bZp2f9PXvttGR8QVYgh9fxirSnULgHf4EmPUkgCfwcBcYVTqpN0l7beXb1uWNMqs2WrTSUofZP7HAKCtI8UwsRvakxC_sYXAQjQmOVhxipsjoNuaZO6Twr4RnaQJsEpKUQxDiuHQnhqsNepIGsYar5AoIpFHezof1r52ADaYbJuY4qLXEzJSzJl-KmYJGpyPwFWX3ymE25wFJKUli0M9j4Z_s2FX_PewL8WiLux6pZ61Q04MTGgX7UeimEFJcxXnVYJuwYPzRnK6Wv9fTo-CTLszdVQrH4wz4SofMXluZyF_56C_gbK_XuJI2LoXNxqN1KaIgQQtOgrM80dHrqUby6L8C2KCl2IUhytjP3-zmRsbEmwWzdCOqGl-jXkaxbd9QpdUj_XkgmZjZG6EA4eKVJrpfKwBceAff6s3sUNHgDSdGwayI4OhW9Hq7Y24HCNwZ7g7Qz2ifLdLdAhblFOGKP5cPAhQZ-iFgog6YjzDHTRm6b-R8Rr01-Ac4WbE0XMF-dcdY0gaqEUdsJNahpQheZ8zxGmAQoYJjr6O4t0TAUVVZs2_8Bb-BmJouzBAgBKePAoHohQ0_AtHkm2A12cYDWSOXArKK2n6vkBnTTbuA4aU9QrON_ENxx9nM6VDRGvQ5zzOnQ_9sU6OwCCWY1b8ghOOOvX-FlUJ49X1X5s1irGhnE7Ou-IVXAFO5cq3pd2DhfsuPei9poW3niyJOFcu9E56vw70ygJEQzwf2sfs2DCJ0Tit7gXGhCcsi32i7_oNV8lj1e2F4CnscXjR8CXVxhJtuYdhvSABLLFq1P_IuWBkpdSxsw-ul2RHekvf08yJcrlxUd8Xb7KvJNpDds74dbGM1jubGFSEgdi0c45KWmz4OnNH2Ua-6rZ12GpR0HwkBaWy4eeyNCl6oyVyjGQRUJMQ4KuzjAGq6MImb8m-2-9n0_KOFYFFZklIydyEhyhRecJ7rXTKyYwjGqcML9l6sffUi5f5HXUA5vLqoYi8sfnY3xZ5q4YeAcY8cRdKShlCjt0ln1kwuRC440EuNJWUPMrNPppWKjfaz-hRtxhDk4hxiwKCbddY74eOwpunkbplrmqHJPzZzeW7KgeKkd_HfoTymWI442bto8rS041nlXLcHc2cilOXpF7zyu6s3q_C5u_oRELTyXTZst5lQwtYNb-K-8V9oVnO_bfW6inmmJAOBa-2Es32lCkf3FEGHocawaXgpT9ZHEyU-izRBz4SWgRZAJab8qBs1QgnNxv0ZGtiJPtMtwkzHRv4jy0cCH6VGYjmN7m2GLJbRjVe3QkVBHYhJnCsDNO92R7Ql3jv3mfd97w6_9wt42QVItM2eY28Rx-M9MhxhAjl6q00TrzLJ4xW_AWB0X_XgHvIld66KOs2UiSVgxp2SGfkg2WeJPpPxuAo-D6vpEkUvnaDMSZm1ZSsqqi0njeFTz8PASxLFOwq7MQptisFxDqjTboE99qxEBDqFkA3ajO2M99MHdRg2FfhChhnEJArf687zLHm-K95GLMisKXRB1Mi5EB4YLtkhh2v_n3p_K9jZmg4b1qT3Y2GEYY589GVgPZliszVxgdahhOZkdyzOEqY9I0ggHZnPncUXmzW4VJ4zbO-fJU1iF6coMr3dsv_hRxkr1h6jLrgwN0uKSRXGIQNSWBPRtwdSTLm-yFHs7S1LOzd1yZiyuWrsl947_w4qRkSyAyb2koePid0HfVcIOL_Mvujy1sf3MuYvpbY1VqKWQXlpe6zdJ-SH4GjdV9YlNhM_XuUzAl1sS09WJlwN3gV0EojRLCpl_r4yMHCGeROIndBZdereYCIC96VNjGANzt3pMS_Th7oKm9ABcCILvJre4WiooIi-24cPgI7Bbz8zSpR_zplhJAxkaqXcNYHFaGZHkjnNbZlPari1rc5txph2BAotmxuqJpLfcWK2SPGWCm0gCMyd-tgmurYaJs9Kl7jbJQNap3ccsG37Oar1sWHdx0TtvbyhxiNXDzdIPCLDq6rJH4tb7pyq_KnBRgw.zMEYVCFScKhxzjLgWVWIMgIaVzuODtdgztbNz_FrBHE\",\"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\":1776125238990},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyNjczOSwiaWF0IjoxNzc2MTIzNDM5LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiI4NDk2Yzk2NS1iNmRlLTRiODgtODg3My01NTYyYWVlNjkzZGIiLCJhdF9oYXNoIjoiYVotX1c0MTUtT2hfcFl2ckFZeEd2QSJ9.VjYrPdj0URFlku7-ePrqNzeX6UqDSROGNnS5_X7Qf0ZqH2S8z6B7jCIEAfz7AQdrH2to58SiCX4lXKf5U9o-qPYuK0AxNPDyo1PeZWQaka13teIm-lVqIiCPE8cHr99vkLaWviAfCxxKDmakdpgThbEo74AKoKQ_u-RVInKScU21Vm_zuXTvmn43szlN0OFydMmvReibB1hSNtEUPNzxbGpC3JkJOUbHSzVVpM9gwJHDJtJERz1GZ5Entbb8micW0ik6ea_FuYmonD4mnA0rluPE7tFk7ij7E36wawjY_zhcV4Du89WD-KwLNEzbtZnHjOzIXuSqq-UXcTW1e6gZrg\"},\"dpopKeyThumbprint\":\"CBxwIIV_loH56FxGGBH2hpXhwGnIiOhlucB5KXMdPMA\",\"issuedAtEpochMs\":1776123438991,\"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\":1776123439000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" + ], + [ + "stellaops:wasEverAuth", + "true" + ] + ] + }, + "events": { + "consoleErrors": [], + "requestFailures": [], + "responseErrors": [] + }, + "statePath": "src/Web/StellaOps.Web/output/playwright/live-release-deployments-proof.state.json" +} diff --git a/src/Web/StellaOps.Web/output/playwright/live-release-deployments-proof.json b/src/Web/StellaOps.Web/output/playwright/live-release-deployments-proof.json new file mode 100644 index 000000000..66fecfa0d --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-release-deployments-proof.json @@ -0,0 +1,13 @@ +{ + "listUrl": "https://stella-ops.local/releases/deployments?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "listTitle": "Deployment History - StellaOps", + "listContainsCheckoutApi": false, + "listContainsNoDeployments": false, + "listHasAbsoluteLink": 0, + "listHasRelativeLink": 0, + "detailUrl": "https://stella-ops.local/releases/deployments/dep-4536d81685ac?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "detailContainsId": false, + "detailContainsCheckoutApi": false, + "detailContainsProduction": true, + "responseErrors": [] +} \ No newline at end of file diff --git a/src/Web/StellaOps.Web/output/playwright/live-release-deployments-proof.state.json b/src/Web/StellaOps.Web/output/playwright/live-release-deployments-proof.state.json new file mode 100644 index 000000000..832743962 --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-release-deployments-proof.state.json @@ -0,0 +1,38 @@ +{ + "cookies": [], + "origins": [ + { + "origin": "https://stella-ops.local", + "localStorage": [ + { + "name": "stellaops.auth.session.full", + "value": "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyNTIzOSwiaWF0IjoxNzc2MTIzNDM5LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiN2UxMDU4MmEtYjZlZi00ZmNjLWFlMTktM2Q4YzZhMDNmZTkxIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMjM0MzksIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.lwYmIBDfA5a43p3EqLuaR2LRkPkL1fSNLWfFA4WgUrhu9uTuOLpoNnQDcp7S8ZSkA8xZ9R0bIiHoDk3qbuYtYOGr7t0gVwd9L97QLxiuPdiD729V_UAF6-aDBhsdFTypsDSrKGxMuDEQ_GLkWpraIAXEhtb01czZkMA4guV7KsGvj4PZOOGVm7CGe_RSDzy2XzcGy29GoHMqa9ausr4kQJTamDGvnVF_n6CRtjBfZepY_uQEtxPMS6xPjR9lXEDf2PwP6CfdBfJXnkA7t_PsnspTnZM0CjJm2fyKAIbCvrOXT47e6d54vZwPPD2PSLAPTeUFuXk9NJTuWFs837P6yg\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.yZg2g96CVWD3R9d-PfDNSugVayYXjeJDrFpC46axzRQOdPlaVZw_XcyOeALIyAIqDSvgjx6g875xjMcjeJnNsyBL2uyzqyf9ZE_CcLJwPgHsjCNp8xnEJg5hkS8taXdzMTB2B3aaVN4wjxYXrTXx9sxBmwsKtTtlNKA6UZ9T8PHMCyOH683quLVipNU-Yy-mZ2e21uKfk81E3ANG4puS987ZQMBO4Ubq_xaKn28FoLq-CqLtw9SnLdc7UM01m9CoxEpjFCG5Xc_DhbTKJWe-6gdOmmK8F5QUOmclOjLoPuAEC8coQm4FFayKOAkHnUDLNs-LiLrCmKhIYZ3Q_OD67w.0K4Ny0kXAkTmAfiqDf0ZlA.6ytX07n70GW1qjnEVkbPg8mdzsanAILxyT3PJ2UVLMlH7zlBVw37kz0DpYV-4gKV2jhsWZ7pCjtRmCUXkNi-lOqR4ebzHvPghtZuBYf__CipUDtlgd6HclNlVCZzAnz2-76JA-J08ldH6-8Ana-ljYxeqc2AXmFAaLmYYGOaFAU76DVnypDp17bjPzJ0pEf3MXvgQWcEBdDe98pCB_VkY5yHkHeM8WG2DCNtyQrpOmVzqJQ-8WK9HugeP87RLdEmbZsZshKkPv1CPl_KYAzmSRj8BeYQmQ70ciqzHn2zWDSj8UHm4vPis9WiufO5zLzTBrIS5t6pwRd3k3GP8YiPOALOJNNXXZWglrN6Tq72DJ7O5j9Hk6MSh0HohfpO3KsicO65UKsu62vXn_I7qZne2yOxg_-nwDav69BJNUZT26QeIDIOJETpFCuKRPBFe058QeQaMAgP-lTtif4DwFgLba519M_4-16YcoH6pXS06Qs5LCIQE4gIEhC1CvsQxA46P7vrjQwEnZVP1f-AjYWFthSlrXrjM8F9JXRg0S4dhYKXZPylOv8k02hOZ28X6tZE3qHXni9v05WDqsPflg0ih3nr2fS7-YJjKrNLllSs8-eDVczjtZeaWEXq-VLHQHmfqQdF3jmVS-MCpjOu13B0C3Hrq7RUWVOmJkQjk7aopcECi7IksmkzpA4EbIcoszsEXHqE_Ixe44mcgIrXDkaLcgnu2F_iDW92qrCjacWWNFeMI5oohlSSL2uKqP5xghvnhvEbbZZ833O_qUqtgovTWOsYnf8fBo1rGhRmwdYHPEDkdTfVMz10zmp3PjhO69z6daSbdDk0Nmi1Qqqdkn6iFec_faXBpwu86GmB3beqySF8c8EDsmAzY7PwIh0O9ioxeUJt4eGuM7ZhqYuLI-LzadqwT7NRZSytxgAChtRV1t1G1X2vrYJ20XOuC6c9_j4Uj11mrOb76g_AHnOg2W6Zkrzv3NCORdmDpHeeqMfIrBhYAG359Szz-QRErJO6LyexUUp5in-n7BwfjFJhosDXduFponKWJiErF1YDPObVRuk6zzrWvuSPO2Wg9PxTrZdnDkgkwmwwvad2VS_TZHgTReXRCb2v5PgnhEWC9_YH2NJbLOHA9c49PdeQE2dcuvAJjMrsZHHVOJ-d0a4eHDPKW9CatJQTfpoJE1TsXWsNyvpwxQhpO2jKByhFY1NRk_s2GI5oEByaxzUCRR5VpNzmXGArKisAMlMPibTls0oKjyFyicOyf0iVILKAaV23gZTir0v_p8x3kqSBaUzItid_Ul5TrEWvU3BTde30OOKZXe2cP0OslJMrAp7cdeEBlwlOtdfnT1GtpLQ4hhk2CMmX4T66-3fs-f8oEx7jBT44QFFXHGbvGN2mOqceq8NmD32Z1eruGjY4ugWUPrFuilT6CMsc9XfhACMIEgNRvQNn9zROUiBKaXgUchqU48iKK1xfeD0X9R1599gg3pAHvstOpf6mUpOKBMGfR6QGmeuIXX28arnF4jpEDPuOVKBBl1UGaqL3WnXcKJpmEZqG_s5eH5TYCVKuzn7fgjYmUT1De9zOe_bl4dloHCNYdtpZNkuANX7xbA0q45ZV2tcWLSrH27FBU8kKBOWKKDmYF9Aau7Irlxu8jUybJs5hOsi9--DbUYWXsXBYfhto_s7sq5_pDLp3yhpfIw25l9m79fnBBWexzHUUIfUiidjzvmFk9vfaHR_NQl6WdLV9NN3jm-n-Sa1NhRou8V6eHOUKxZltqjG3Fm_A26MTJzXqw50PMKkq5VHe55FXf3R0eZWkqLgePI_xwreWbyufVuN92xarTOwt-MVsN_xOG6vtrcW20ofaMhSf8LHBg2IodK44bGJKjsN2DRWigHNGXNA5AKjRkgCGMB29-zau3P2EQ6DyxjtCQcvdfDjlKoL40bOPwofgSSukD3gTT0eN1VMGFn6cFC1Igo_2JBTUPN2Lmp0l8ubDEBkFNSnKg9b-UlpokN23V7Mhpzeibv07JgCxP-UlNm9XYo2qk6Ph_eT-gVPiCRbeWoi9qgELL_WK8stQaDXz6IYDq3rCscne7LHU5Y_yIhuVEsxsfcTtDDkq3tULgkFZ9wd9oQnKubJRlhL3BVBOAmzgUjNvSSuD89FzKAFo4K8FrzxUmOqXDyI1jGsesKrnoeBzI3MNXXm_Ff9oK7g3QjrwZ4V9uOoDvRxLNU1-DxiZHT2TPPEyOxuetqzV-gLqg6EDmRELGMpkHv6D1Kryx46URrwIeGRPwUt8X0rmbMHjwWmifrHPTlzcLsZ7EIajgiqF-HRMxZdMntoQFBb9WWLu9IBM1s7cVkLM97wbszFvUkTn8ChfdBkNnwjVwFeg8mDWRwDqfpaJ6YpWvzF_yz1IK-Qt9IOEqjcav_b9Oy5np3PYRLC1WYP9MWo9-Cnp6nN7MjrV-HJnsR5sh2VXUJNIFK19BEm1_11DXidw2b4uMe3TXjELK52k5g4lIrdOQnS87udUqhc1szfzjaWULjF2FwRCERewgJ6zg7wxymjMenyu5YDlWga2tPUCJmEA8vFLZjsr9hnpekDSa_Wu25OdbSsjKNg9aQJzBzpX5upZrOE4nJvG7-bTyUde7sHF4yqNxD_UbOPVkjcNpUBfNJtseqwnXdOu1EAMC5GuHmW78EQh7ZId7x7pnw8mUjd7l1Mn4TK3I645fYpk1OP3z5VDFfpncwC2-YF9mpJUIYp3-LhXoS61y7bZp2f9PXvttGR8QVYgh9fxirSnULgHf4EmPUkgCfwcBcYVTqpN0l7beXb1uWNMqs2WrTSUofZP7HAKCtI8UwsRvakxC_sYXAQjQmOVhxipsjoNuaZO6Twr4RnaQJsEpKUQxDiuHQnhqsNepIGsYar5AoIpFHezof1r52ADaYbJuY4qLXEzJSzJl-KmYJGpyPwFWX3ymE25wFJKUli0M9j4Z_s2FX_PewL8WiLux6pZ61Q04MTGgX7UeimEFJcxXnVYJuwYPzRnK6Wv9fTo-CTLszdVQrH4wz4SofMXluZyF_56C_gbK_XuJI2LoXNxqN1KaIgQQtOgrM80dHrqUby6L8C2KCl2IUhytjP3-zmRsbEmwWzdCOqGl-jXkaxbd9QpdUj_XkgmZjZG6EA4eKVJrpfKwBceAff6s3sUNHgDSdGwayI4OhW9Hq7Y24HCNwZ7g7Qz2ifLdLdAhblFOGKP5cPAhQZ-iFgog6YjzDHTRm6b-R8Rr01-Ac4WbE0XMF-dcdY0gaqEUdsJNahpQheZ8zxGmAQoYJjr6O4t0TAUVVZs2_8Bb-BmJouzBAgBKePAoHohQ0_AtHkm2A12cYDWSOXArKK2n6vkBnTTbuA4aU9QrON_ENxx9nM6VDRGvQ5zzOnQ_9sU6OwCCWY1b8ghOOOvX-FlUJ49X1X5s1irGhnE7Ou-IVXAFO5cq3pd2DhfsuPei9poW3niyJOFcu9E56vw70ygJEQzwf2sfs2DCJ0Tit7gXGhCcsi32i7_oNV8lj1e2F4CnscXjR8CXVxhJtuYdhvSABLLFq1P_IuWBkpdSxsw-ul2RHekvf08yJcrlxUd8Xb7KvJNpDds74dbGM1jubGFSEgdi0c45KWmz4OnNH2Ua-6rZ12GpR0HwkBaWy4eeyNCl6oyVyjGQRUJMQ4KuzjAGq6MImb8m-2-9n0_KOFYFFZklIydyEhyhRecJ7rXTKyYwjGqcML9l6sffUi5f5HXUA5vLqoYi8sfnY3xZ5q4YeAcY8cRdKShlCjt0ln1kwuRC440EuNJWUPMrNPppWKjfaz-hRtxhDk4hxiwKCbddY74eOwpunkbplrmqHJPzZzeW7KgeKkd_HfoTymWI442bto8rS041nlXLcHc2cilOXpF7zyu6s3q_C5u_oRELTyXTZst5lQwtYNb-K-8V9oVnO_bfW6inmmJAOBa-2Es32lCkf3FEGHocawaXgpT9ZHEyU-izRBz4SWgRZAJab8qBs1QgnNxv0ZGtiJPtMtwkzHRv4jy0cCH6VGYjmN7m2GLJbRjVe3QkVBHYhJnCsDNO92R7Ql3jv3mfd97w6_9wt42QVItM2eY28Rx-M9MhxhAjl6q00TrzLJ4xW_AWB0X_XgHvIld66KOs2UiSVgxp2SGfkg2WeJPpPxuAo-D6vpEkUvnaDMSZm1ZSsqqi0njeFTz8PASxLFOwq7MQptisFxDqjTboE99qxEBDqFkA3ajO2M99MHdRg2FfhChhnEJArf687zLHm-K95GLMisKXRB1Mi5EB4YLtkhh2v_n3p_K9jZmg4b1qT3Y2GEYY589GVgPZliszVxgdahhOZkdyzOEqY9I0ggHZnPncUXmzW4VJ4zbO-fJU1iF6coMr3dsv_hRxkr1h6jLrgwN0uKSRXGIQNSWBPRtwdSTLm-yFHs7S1LOzd1yZiyuWrsl947_w4qRkSyAyb2koePid0HfVcIOL_Mvujy1sf3MuYvpbY1VqKWQXlpe6zdJ-SH4GjdV9YlNhM_XuUzAl1sS09WJlwN3gV0EojRLCpl_r4yMHCGeROIndBZdereYCIC96VNjGANzt3pMS_Th7oKm9ABcCILvJre4WiooIi-24cPgI7Bbz8zSpR_zplhJAxkaqXcNYHFaGZHkjnNbZlPari1rc5txph2BAotmxuqJpLfcWK2SPGWCm0gCMyd-tgmurYaJs9Kl7jbJQNap3ccsG37Oar1sWHdx0TtvbyhxiNXDzdIPCLDq6rJH4tb7pyq_KnBRgw.zMEYVCFScKhxzjLgWVWIMgIaVzuODtdgztbNz_FrBHE\",\"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\":1776125238990},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyNjczOSwiaWF0IjoxNzc2MTIzNDM5LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiI4NDk2Yzk2NS1iNmRlLTRiODgtODg3My01NTYyYWVlNjkzZGIiLCJhdF9oYXNoIjoiYVotX1c0MTUtT2hfcFl2ckFZeEd2QSJ9.VjYrPdj0URFlku7-ePrqNzeX6UqDSROGNnS5_X7Qf0ZqH2S8z6B7jCIEAfz7AQdrH2to58SiCX4lXKf5U9o-qPYuK0AxNPDyo1PeZWQaka13teIm-lVqIiCPE8cHr99vkLaWviAfCxxKDmakdpgThbEo74AKoKQ_u-RVInKScU21Vm_zuXTvmn43szlN0OFydMmvReibB1hSNtEUPNzxbGpC3JkJOUbHSzVVpM9gwJHDJtJERz1GZ5Entbb8micW0ik6ea_FuYmonD4mnA0rluPE7tFk7ij7E36wawjY_zhcV4Du89WD-KwLNEzbtZnHjOzIXuSqq-UXcTW1e6gZrg\"},\"dpopKeyThumbprint\":\"CBxwIIV_loH56FxGGBH2hpXhwGnIiOhlucB5KXMdPMA\",\"issuedAtEpochMs\":1776123438991,\"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\":1776123439000,\"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}" + }, + { + "name": "stellaops.theme", + "value": "system" + }, + { + "name": "stellaops.auth.session.info", + "value": "{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"expiresAtEpochMs\":1776125238990,\"issuedAtEpochMs\":1776123438991,\"dpopKeyThumbprint\":\"CBxwIIV_loH56FxGGBH2hpXhwGnIiOhlucB5KXMdPMA\",\"tenantId\":\"demo-prod\"}" + }, + { + "name": "stellaops.sidebar.preferences", + "value": "{\"sidebarCollapsed\":false,\"collapsedGroups\":[\"evidence\",\"setup-admin\"],\"collapsedSections\":[]}" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/Web/StellaOps.Web/output/playwright/live-release-environments.auth.json b/src/Web/StellaOps.Web/output/playwright/live-release-environments.auth.json new file mode 100644 index 000000000..308d18ebc --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-release-environments.auth.json @@ -0,0 +1,85 @@ +{ + "authenticatedAtUtc": "2026-04-13T20:45:50.109Z", + "baseUrl": "https://stella-ops.local", + "finalUrl": "https://stella-ops.local/?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Dashboard - StellaOps", + "cookies": [], + "storage": { + "localStorageEntries": [ + [ + "stellaops.auth.session.full", + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjExNDk0NiwiaWF0IjoxNzc2MTEzMTQ2LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiNWNlMGUwNjItOWE4Zi00MjBjLWJjMjgtMWY1YTU0ZmEzMDA5Iiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMTMxNDYsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.iRgTzRk-RTHOTl6v4R8NqLXW9W-0WHkNdvDpDGhhJKJDZ6s0JygHiralN5oX_c-2DXZwihAYtefR5YnaBOgDzLmPmp8WN8V7J3BebrkInEfHDwT6JuTlNECXbWqs3JRJR6qzBat3qE335cyfKIIjPW7jGhqaHWZUs0EwFV0cTljn-M-BXztVlB7ixWHqEk-JeYiLJ2he58zhmU0LZX9imk800i3IGFjd6O2NyVbAtXshUJ2DauN28Yv-FdAXn3l6Q2r0zyrfOzburgd7ob-ewzaT6qCS3ccs8wRKSA7MqJ0FV_yfP6j10yjSmUpWfX-LHr4DpiktQvXtOLBSlRNZ_w\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.K7sT2dR_vyCjOiDRfxHPkmm5KmK2UTKqjLngPZvp_nUKwz4b7-RMHzeDmq1gXSSWwqfIB4Q_eg75XR87Mn_efjUvcoksDB1qwWFmTqA4-mTqIekMDf0-ng364HlgD82lu9_8XznzjC_NHvRW7569BPieAeel0ujFdNinq6jGHdgE98Lfb1Pt4_4h0rRVud-vsxxUBIMdI8nUzPjg_qAFdrBxf16CnAS58lU3Km7mheZl-bAmI6ke5zQU1AWPv9xBApeFtdWBLcVXtwtXLb_7VkVDXNs_dPoBCO6rIgOXZSwHa77KCyQhsL8a6lN9EuJ7BZwruDllo6NiObJEgglKmA.s_URdF4yamP_LlT8fBpXZQ.M4Hzmb0obrv4ahq6AKsrT2ilWkzBes5SmWeYkej3_33eTKExxBYIAB0XlJx2FEu58P2SvRrtdkOla92vcnBChJCInREFFXpNZCswIBqK0DB6caw_bDMGhlLp97nJf-xNiESsLSik88-puuSp1J0I4vhrgDyuJq04B32uWlj1YUkxV5ANDwzK3hPRRM7qarz7M5MpbzFRhsnF7Qd4i8ClD04IPRFui_Syy7N5wRyhvVUm8ZQgEa_8jobA6Jfi298_mvyi8gRjEq5P1jNOiuP0WW_txQ8Uqiafnu_LrRAYCW9XpFL7QoRXt2iB3jt3G7c7mqxI5WfvZCmmZhxHbTDp4o4PBAiX-e1LQIXqoUKRlDr7Gy8PPdOGLK66OJtL0uaCTwRQuWG2eBeFzdEgUQeGLcDyO7CZPFewPHgpCHQuHspA5RwfXgH9zI_4UxPQud8L1-5u5PduWAvH_4yw9TRl78pZxxPtBT0zQNz4RZOc2xRHie9WLsWzrogL6dSxSth3kgK4Yy_SIdJ65BL5zp-h1komXRhpfWlFxjMGsMMMlmjeCHwuQSwHNa8nZhBw7O8QaJ7kxwyQx-e6V13120MNCjlTsEoEIIIk6BAVlHDxGz9p_feRFoAo8jo5pG4BfKlQVZxRiaLH4xtmPxktVSQPy-zywJzb_43d5xwLY_fxdRa787HmwXizS2Ee_mqU32Sy8uzNi5qgwPoLSbJu4urbPzXjOAf58mU1ifvXWGmS6JLOR_vXJZ3q-zLt--9vXQl4LIg4SWgNSmyO1JpxL8s9K7lPTsG023dWB3cWA8hnQoqt5iNHjypkPxJJhXgS1O43JSZ5KHN1Y9QHvbobv2Fb-SfEYtqxLiVi9bh0_p9cU0NKm5a-QxWyIwqx-1RSuJYYM8nxjvilEPuBLYT1u8DCGxkkxg6WJz3wooQWM_XFs79H4VeV1yR3PmB5JxSxqEhprv6QxAX1y5KPRuLMCrGkrATtYvLfbg8yWThC_dK1hC3Y6Vwt9gnVDfWuHPp18yswiuWB-CdaMd3NGll7Qrl4CgLBycUXTQRZ-qMzW0I8cMrtvDozc1KjK073vRUOJvCS1rqm5C-f42ECE6NsNkdbAIQWjFOTCV8S9zJ6bunHKUdT9WH6UU9MOUBQXD7PmUYowPQ9JS-oG1YHwUFB9JfFZ6fcdYyqAcLd1_STg5_vOIv9ln457zpxoJykRd-95HJiHflD53-w2rcbkgdlC8_dJD6qxSUpy3hKd3k6U65DoU-WDuacvqq6514eztcV4ktLIfyij7YS-ZuCrFYyy7y0Di9EOEqSAXcFyqGumgT5Vra_GE4Nl6_O0sePmKV-4NA0l0LF7Hp-9xEmCIu1TONmyYpTr4oDrAMbIE9rnIBhe6ThGYy5qudj3LaKuHG3hgJgdC27m3qUNTEYpids-IYhsNgqNIGDnuI8ypyIBw_hVJnDe59N3LxpIH81j0K-_Gp8DLQqpSC-LhgMp8IZgz-dAi3OhpCAk-dC77lkNfFPyI8MdRV-2JMxw33sDQXoO-q8K6PfeLcxqf-d187OyC3cffSSTixyGRSvkNP71MGW3vGqTs8A74RNo6MR_RvZqQCEArAZaJUkvV2VsO73MEHWgrc2_xezdnFilvUB3d7nk28X_LjemwQfz1uB7rEkXqmQgo8huBBQ5cXY41oe8qalPthWphaEaNmSFIfD0tXGDesgmyN3ErEctXWyfZ_p3Gn6cL5G38JEQGEROvCJlmN8Oo3Ntbs2jy3ekGow72xsGGDfD9tKfwZWp13J18ewS8DKq1RpEV1pdaconBVYY34v9H8Tt1LIc_HxocfYHL2-7LYHStMIOYv8ftJ6aQ6TyIWtTTjKXdLjNVIlN7v4S-yxJItlmHdSFycQ8FuZDFvzwmhQ8yir3ES2TRWdIgO30bBrjQggfjPjvIs6m2ZWv3Aejv6cvbnonAUAqpQxCb2AYT5DNcKXxccLRJNaIOKCUjRIq97sp02fOSQT4zlN48ExqJoploFYBJNgs17k6nWwpIFwz0cdGP0zSu9CeLF6nZn4yfNs2p72T3uY4riuA5KCUYGr62ZW6r-jcE29SSBq5WPKwaWuTjT9NwQbFDzu0YXdq4jrg5OrGZp7cY5XMDuQmuX3Z7PvbfVlGmyjuuwIF1x4ZWRLkRbWfhvz6oBpAXp4VCKKvfwXV1xh1zyRSzBSAN4VMtcU6-a7ZR4Z8kh9yitLFPx8sRFWbCrbOy6AZqlio8gcPJxVbExny8A_Znt4E8ehxcoR-vDinmmCE1MedOThid4rFYWjZNEIStS5XeZI44jHlIuZeDfGTsxbDoXWEPDWh9WSSbp_JVyySyUNjL2hO7lcvm-MeslTlWsVgOPoY5vgvPmxges3P6DAoDFLecoCvrLh1ljxe30hqmMQqeZKq_UxoUd-1-lKWHjLuJAhg7L8q1y1JgHan45fZxb8jg_EP16AwPkkoONizFYLu78LDNWSZusYeYpsr2RM6YzDl1GYgYOf1LUl0BJ2nQU8ypzqziYRv8mJPOpYX10uLntygO0Kz_i4lU7xPI3w_yPAsCzcuwFsgZ1y2GpRwUAYMyhTYM9k2f96SJ4FAtFiiJKbD9QX3PzCcV794TKkrOO3Jl3kLBAN6pGByeOySJNZcgVS00NDw8SZ6zSWjLmD_rvWv6y_md2d4C8vqAs2SfPSUqO31HWaeOPuc-OeyeVBWt169jiE6F1MlZYbBOV8p-zBQ1zUq9fDIbi-wBdtnMqv52OvubOXz1hkOkAA7VzroqMyAmRx98FHYy6qzI4wZKjyKN4laez2FZLqBUqbEnxexhfvYYAnqqKtz35lktX0G-i9NAWSS_73WTsDlG4o20tGb8T6lrqIiscwWlxd_IxrC6g8lsLDc0pySr9vGYMVzAvFoEiVRwMMoAy7J81VcYaYwwwLNGY6gElCSfwcpudx8-46wJFGUYEhMe4-5Z3dt91HTbWXDBVY28fGnClubwCs-Ge1BQHbcekM_sBNCt00VpWeJx9TYrUtCP6w4-GX3h_8XQI65GnaEsZFpUzeNpd6hBLCW2GDr5CxJgefAvp0a2Hp4IxQWR6NSPp-VR7MTKbcb1ZUUKniEa4ZFL9VKI4Ovo06F0Ue2L_47EcSXzsn4RSSKjuTq-0ftsuoKXozV5m5q--BaBqNS4nfTz5NEE2TWCRMIRSCo1u_BZT_jRx7bDdswwZGK81m-ZqLcRV3fDr0HgGENVZkBbtRJYmn6FpqH9-6PyRvPSOyyX6MyaRAzIjWVMfP3ZBxbvcTRl_71fhCGHCgNsZ5GjHprcynMLsZg9bpttCmwVAVZUK0wOEFqlVgXt71LkiCSGEt1ISR1siQwaIxQ7LjG8tfwjBtkwJjNKc-hgBkiHh7MDJGgAAApr3gIV8EOaJi7_A7L4Bgo7UIJT8b1YSuXAqr0tMShuQ80FRVk1ravJHA2XpKJCsah3eJz7DCOWt11P69m_xjRCSZg6GI3-uCH6sU7SrtfZL6G7ZzrLpOENIb3AoAlmXJXPfIB8WWO8U_ygAcc5BA7-ZmNaFzeFTSTdBQHPSD278qM6L85DG-OFKIobVH8sMWnc6ZY9OV23s352N7CTtRf3E4OxEgpXozR6zBc-n1cXMEiVi0RdzBWWBFvfRCgAyyQLFAXKAXY6wlm07u9kA4S8ANrV1yYhLZdvVaLY2k0ThktrcvVDQ7wzqKNU3jKkkHwP_dTmLz-PtzZaaJla8IEn9suThrS-OMYKMYFHRBs71fUIwyP7vomhObrOd8X5GsWiXI2bIa3gNcfCVAw76K6LuEVc-3RqJ8LO4PaD9hoWl7YMbsv2iJXVlaBNJIJPR_2_3ZJYLssekYL_6SDnUrs4g-QXcLvY30cPQ1ICCx90hn38pYJOgeMWHrDEAuTgQMN0hA7ynoFgDx-_VVFORn0HiidM1Eh0Vp1oMdzfFPjerQJ65KhRO5TVEARQ7zosxjMMSXcq7LgEoqmtFNMDOeG-p8HR4pK_5aldcjBPxO29I-G58JivOfXvT-JblOzHj7hascqtGKpPdYZipB41iQVzFyVO0CL4hYVOa9Rvr-Vfk2unXgizTZaXFtnDwi8Km3Q4qVjJsQxDTPW9HgzxhqvRX9mW3QZMpsR_msPby46Tp-aOcEwVJcgviVIbdiFb3jPzRx7WpdKVY56tqeyqDtUherMMe_u42xMVEBZmvByLcjMyLZZUkQNAAgsaHazofZX3EDFTv-gXLJAZFvYJW4RS9fC6RpYlCzfaYNTI2WRvYzmIxebf8MNAH2Y-FVcWCAsGZB_z9ZCApfIAxbzEQqItFmWxEZqHB7qUbleZcYE_LTm7sNlUDOmF3VeW7qyspVOfSnT7N_mqW8TkZZ1SdaT2YcjLVjIvxTjQIjVbcsq52MA39UelR5ea8NkhSXv-u58YtQ7y8VHC_FeH7GErDJkc6HIE1q7PJ2IK-UtkwktY8NJWbEudNeRQsWG2n7mls9b2i-18NtyHk63v_FdUVXodAXa6oisKn_antJXcxRiLeMOHy7ooMDSV583oS3_ri2bZn31TO2cOsfUL4ffyOJSjHXgra5V6H2HNc_LNKo4QIJTaIHNreId0WA3lhCRy8fjaqb2-8jESQWqeQETfXEGf0NDIwG7LQ0MXaCAOiqdCIjN8DycCinIS_kWMW0WwfBujOkj7aPUH01JhtUdE9FDbwdD_sT1V2uUxJOwKY5voZrlI8_cD0kipY_E-NdiotJwF-A95gc0go9_6OSBxOWcQ.N9axeExjDktt2OgN_bzhv352BhcEjih2QK1oR1HMlqk\",\"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\":1776114946514},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjExNjQ0NiwiaWF0IjoxNzc2MTEzMTQ2LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiJmZjY1ZTFhMy05MTA0LTQxNjItYTc4NS0yOWYzY2JkNzgwOTQiLCJhdF9oYXNoIjoiM2d5NEJCNk0tSEY5Z3NWd0ZMOFNqdyJ9.FS8zk7aSd1cheJGsRFszaQkbHIQBdm_1h8EB9ObjbZLo1w1amR7HMM-e2eLn_bv7mYZVIxV4NWHzqYZi19HVKFbuMkUDBQ1r9xEuwFIv7LmjvlTttBiXg6GAHCqWsXxV0_yN6y91ISG4dy3FKAWdd8Y9L-rIjRc6p5w8m1zdG-rnq4cO2O-uCOfRNMse_r7kYW5WY1IY3bKOvO_gi3ySwzZAtPI-PFWoEpy3PszeM_d343B_ZR-2wsmX5sZeyZP-ma_VYVktKVpVfm0mr6SZnCC9MpdUn1eKTpX2tyM-jm9_LZlOGkU8ClaRRMyFEH5SX5G_Q1ONyVAu5EEoYolp-Q\"},\"dpopKeyThumbprint\":\"8LW6CUuNAsgCC2G2M4XmoieSP8kcaatZLfqvyDQtVXQ\",\"issuedAtEpochMs\":1776113147515,\"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\":1776113146000,\"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}" + ], + [ + "stellaops.theme", + "system" + ], + [ + "stellaops.auth.session.info", + "{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"expiresAtEpochMs\":1776114946514,\"issuedAtEpochMs\":1776113147515,\"dpopKeyThumbprint\":\"8LW6CUuNAsgCC2G2M4XmoieSP8kcaatZLfqvyDQtVXQ\",\"tenantId\":\"demo-prod\"}" + ], + [ + "stellaops.sidebar.preferences", + "{\"sidebarCollapsed\":false,\"collapsedGroups\":[\"evidence\",\"setup-admin\"],\"collapsedSections\":[]}" + ] + ], + "sessionStorageEntries": [ + [ + "stellaops.auth.session.full", + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjExNDk0NiwiaWF0IjoxNzc2MTEzMTQ2LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiNWNlMGUwNjItOWE4Zi00MjBjLWJjMjgtMWY1YTU0ZmEzMDA5Iiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMTMxNDYsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.iRgTzRk-RTHOTl6v4R8NqLXW9W-0WHkNdvDpDGhhJKJDZ6s0JygHiralN5oX_c-2DXZwihAYtefR5YnaBOgDzLmPmp8WN8V7J3BebrkInEfHDwT6JuTlNECXbWqs3JRJR6qzBat3qE335cyfKIIjPW7jGhqaHWZUs0EwFV0cTljn-M-BXztVlB7ixWHqEk-JeYiLJ2he58zhmU0LZX9imk800i3IGFjd6O2NyVbAtXshUJ2DauN28Yv-FdAXn3l6Q2r0zyrfOzburgd7ob-ewzaT6qCS3ccs8wRKSA7MqJ0FV_yfP6j10yjSmUpWfX-LHr4DpiktQvXtOLBSlRNZ_w\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.K7sT2dR_vyCjOiDRfxHPkmm5KmK2UTKqjLngPZvp_nUKwz4b7-RMHzeDmq1gXSSWwqfIB4Q_eg75XR87Mn_efjUvcoksDB1qwWFmTqA4-mTqIekMDf0-ng364HlgD82lu9_8XznzjC_NHvRW7569BPieAeel0ujFdNinq6jGHdgE98Lfb1Pt4_4h0rRVud-vsxxUBIMdI8nUzPjg_qAFdrBxf16CnAS58lU3Km7mheZl-bAmI6ke5zQU1AWPv9xBApeFtdWBLcVXtwtXLb_7VkVDXNs_dPoBCO6rIgOXZSwHa77KCyQhsL8a6lN9EuJ7BZwruDllo6NiObJEgglKmA.s_URdF4yamP_LlT8fBpXZQ.M4Hzmb0obrv4ahq6AKsrT2ilWkzBes5SmWeYkej3_33eTKExxBYIAB0XlJx2FEu58P2SvRrtdkOla92vcnBChJCInREFFXpNZCswIBqK0DB6caw_bDMGhlLp97nJf-xNiESsLSik88-puuSp1J0I4vhrgDyuJq04B32uWlj1YUkxV5ANDwzK3hPRRM7qarz7M5MpbzFRhsnF7Qd4i8ClD04IPRFui_Syy7N5wRyhvVUm8ZQgEa_8jobA6Jfi298_mvyi8gRjEq5P1jNOiuP0WW_txQ8Uqiafnu_LrRAYCW9XpFL7QoRXt2iB3jt3G7c7mqxI5WfvZCmmZhxHbTDp4o4PBAiX-e1LQIXqoUKRlDr7Gy8PPdOGLK66OJtL0uaCTwRQuWG2eBeFzdEgUQeGLcDyO7CZPFewPHgpCHQuHspA5RwfXgH9zI_4UxPQud8L1-5u5PduWAvH_4yw9TRl78pZxxPtBT0zQNz4RZOc2xRHie9WLsWzrogL6dSxSth3kgK4Yy_SIdJ65BL5zp-h1komXRhpfWlFxjMGsMMMlmjeCHwuQSwHNa8nZhBw7O8QaJ7kxwyQx-e6V13120MNCjlTsEoEIIIk6BAVlHDxGz9p_feRFoAo8jo5pG4BfKlQVZxRiaLH4xtmPxktVSQPy-zywJzb_43d5xwLY_fxdRa787HmwXizS2Ee_mqU32Sy8uzNi5qgwPoLSbJu4urbPzXjOAf58mU1ifvXWGmS6JLOR_vXJZ3q-zLt--9vXQl4LIg4SWgNSmyO1JpxL8s9K7lPTsG023dWB3cWA8hnQoqt5iNHjypkPxJJhXgS1O43JSZ5KHN1Y9QHvbobv2Fb-SfEYtqxLiVi9bh0_p9cU0NKm5a-QxWyIwqx-1RSuJYYM8nxjvilEPuBLYT1u8DCGxkkxg6WJz3wooQWM_XFs79H4VeV1yR3PmB5JxSxqEhprv6QxAX1y5KPRuLMCrGkrATtYvLfbg8yWThC_dK1hC3Y6Vwt9gnVDfWuHPp18yswiuWB-CdaMd3NGll7Qrl4CgLBycUXTQRZ-qMzW0I8cMrtvDozc1KjK073vRUOJvCS1rqm5C-f42ECE6NsNkdbAIQWjFOTCV8S9zJ6bunHKUdT9WH6UU9MOUBQXD7PmUYowPQ9JS-oG1YHwUFB9JfFZ6fcdYyqAcLd1_STg5_vOIv9ln457zpxoJykRd-95HJiHflD53-w2rcbkgdlC8_dJD6qxSUpy3hKd3k6U65DoU-WDuacvqq6514eztcV4ktLIfyij7YS-ZuCrFYyy7y0Di9EOEqSAXcFyqGumgT5Vra_GE4Nl6_O0sePmKV-4NA0l0LF7Hp-9xEmCIu1TONmyYpTr4oDrAMbIE9rnIBhe6ThGYy5qudj3LaKuHG3hgJgdC27m3qUNTEYpids-IYhsNgqNIGDnuI8ypyIBw_hVJnDe59N3LxpIH81j0K-_Gp8DLQqpSC-LhgMp8IZgz-dAi3OhpCAk-dC77lkNfFPyI8MdRV-2JMxw33sDQXoO-q8K6PfeLcxqf-d187OyC3cffSSTixyGRSvkNP71MGW3vGqTs8A74RNo6MR_RvZqQCEArAZaJUkvV2VsO73MEHWgrc2_xezdnFilvUB3d7nk28X_LjemwQfz1uB7rEkXqmQgo8huBBQ5cXY41oe8qalPthWphaEaNmSFIfD0tXGDesgmyN3ErEctXWyfZ_p3Gn6cL5G38JEQGEROvCJlmN8Oo3Ntbs2jy3ekGow72xsGGDfD9tKfwZWp13J18ewS8DKq1RpEV1pdaconBVYY34v9H8Tt1LIc_HxocfYHL2-7LYHStMIOYv8ftJ6aQ6TyIWtTTjKXdLjNVIlN7v4S-yxJItlmHdSFycQ8FuZDFvzwmhQ8yir3ES2TRWdIgO30bBrjQggfjPjvIs6m2ZWv3Aejv6cvbnonAUAqpQxCb2AYT5DNcKXxccLRJNaIOKCUjRIq97sp02fOSQT4zlN48ExqJoploFYBJNgs17k6nWwpIFwz0cdGP0zSu9CeLF6nZn4yfNs2p72T3uY4riuA5KCUYGr62ZW6r-jcE29SSBq5WPKwaWuTjT9NwQbFDzu0YXdq4jrg5OrGZp7cY5XMDuQmuX3Z7PvbfVlGmyjuuwIF1x4ZWRLkRbWfhvz6oBpAXp4VCKKvfwXV1xh1zyRSzBSAN4VMtcU6-a7ZR4Z8kh9yitLFPx8sRFWbCrbOy6AZqlio8gcPJxVbExny8A_Znt4E8ehxcoR-vDinmmCE1MedOThid4rFYWjZNEIStS5XeZI44jHlIuZeDfGTsxbDoXWEPDWh9WSSbp_JVyySyUNjL2hO7lcvm-MeslTlWsVgOPoY5vgvPmxges3P6DAoDFLecoCvrLh1ljxe30hqmMQqeZKq_UxoUd-1-lKWHjLuJAhg7L8q1y1JgHan45fZxb8jg_EP16AwPkkoONizFYLu78LDNWSZusYeYpsr2RM6YzDl1GYgYOf1LUl0BJ2nQU8ypzqziYRv8mJPOpYX10uLntygO0Kz_i4lU7xPI3w_yPAsCzcuwFsgZ1y2GpRwUAYMyhTYM9k2f96SJ4FAtFiiJKbD9QX3PzCcV794TKkrOO3Jl3kLBAN6pGByeOySJNZcgVS00NDw8SZ6zSWjLmD_rvWv6y_md2d4C8vqAs2SfPSUqO31HWaeOPuc-OeyeVBWt169jiE6F1MlZYbBOV8p-zBQ1zUq9fDIbi-wBdtnMqv52OvubOXz1hkOkAA7VzroqMyAmRx98FHYy6qzI4wZKjyKN4laez2FZLqBUqbEnxexhfvYYAnqqKtz35lktX0G-i9NAWSS_73WTsDlG4o20tGb8T6lrqIiscwWlxd_IxrC6g8lsLDc0pySr9vGYMVzAvFoEiVRwMMoAy7J81VcYaYwwwLNGY6gElCSfwcpudx8-46wJFGUYEhMe4-5Z3dt91HTbWXDBVY28fGnClubwCs-Ge1BQHbcekM_sBNCt00VpWeJx9TYrUtCP6w4-GX3h_8XQI65GnaEsZFpUzeNpd6hBLCW2GDr5CxJgefAvp0a2Hp4IxQWR6NSPp-VR7MTKbcb1ZUUKniEa4ZFL9VKI4Ovo06F0Ue2L_47EcSXzsn4RSSKjuTq-0ftsuoKXozV5m5q--BaBqNS4nfTz5NEE2TWCRMIRSCo1u_BZT_jRx7bDdswwZGK81m-ZqLcRV3fDr0HgGENVZkBbtRJYmn6FpqH9-6PyRvPSOyyX6MyaRAzIjWVMfP3ZBxbvcTRl_71fhCGHCgNsZ5GjHprcynMLsZg9bpttCmwVAVZUK0wOEFqlVgXt71LkiCSGEt1ISR1siQwaIxQ7LjG8tfwjBtkwJjNKc-hgBkiHh7MDJGgAAApr3gIV8EOaJi7_A7L4Bgo7UIJT8b1YSuXAqr0tMShuQ80FRVk1ravJHA2XpKJCsah3eJz7DCOWt11P69m_xjRCSZg6GI3-uCH6sU7SrtfZL6G7ZzrLpOENIb3AoAlmXJXPfIB8WWO8U_ygAcc5BA7-ZmNaFzeFTSTdBQHPSD278qM6L85DG-OFKIobVH8sMWnc6ZY9OV23s352N7CTtRf3E4OxEgpXozR6zBc-n1cXMEiVi0RdzBWWBFvfRCgAyyQLFAXKAXY6wlm07u9kA4S8ANrV1yYhLZdvVaLY2k0ThktrcvVDQ7wzqKNU3jKkkHwP_dTmLz-PtzZaaJla8IEn9suThrS-OMYKMYFHRBs71fUIwyP7vomhObrOd8X5GsWiXI2bIa3gNcfCVAw76K6LuEVc-3RqJ8LO4PaD9hoWl7YMbsv2iJXVlaBNJIJPR_2_3ZJYLssekYL_6SDnUrs4g-QXcLvY30cPQ1ICCx90hn38pYJOgeMWHrDEAuTgQMN0hA7ynoFgDx-_VVFORn0HiidM1Eh0Vp1oMdzfFPjerQJ65KhRO5TVEARQ7zosxjMMSXcq7LgEoqmtFNMDOeG-p8HR4pK_5aldcjBPxO29I-G58JivOfXvT-JblOzHj7hascqtGKpPdYZipB41iQVzFyVO0CL4hYVOa9Rvr-Vfk2unXgizTZaXFtnDwi8Km3Q4qVjJsQxDTPW9HgzxhqvRX9mW3QZMpsR_msPby46Tp-aOcEwVJcgviVIbdiFb3jPzRx7WpdKVY56tqeyqDtUherMMe_u42xMVEBZmvByLcjMyLZZUkQNAAgsaHazofZX3EDFTv-gXLJAZFvYJW4RS9fC6RpYlCzfaYNTI2WRvYzmIxebf8MNAH2Y-FVcWCAsGZB_z9ZCApfIAxbzEQqItFmWxEZqHB7qUbleZcYE_LTm7sNlUDOmF3VeW7qyspVOfSnT7N_mqW8TkZZ1SdaT2YcjLVjIvxTjQIjVbcsq52MA39UelR5ea8NkhSXv-u58YtQ7y8VHC_FeH7GErDJkc6HIE1q7PJ2IK-UtkwktY8NJWbEudNeRQsWG2n7mls9b2i-18NtyHk63v_FdUVXodAXa6oisKn_antJXcxRiLeMOHy7ooMDSV583oS3_ri2bZn31TO2cOsfUL4ffyOJSjHXgra5V6H2HNc_LNKo4QIJTaIHNreId0WA3lhCRy8fjaqb2-8jESQWqeQETfXEGf0NDIwG7LQ0MXaCAOiqdCIjN8DycCinIS_kWMW0WwfBujOkj7aPUH01JhtUdE9FDbwdD_sT1V2uUxJOwKY5voZrlI8_cD0kipY_E-NdiotJwF-A95gc0go9_6OSBxOWcQ.N9axeExjDktt2OgN_bzhv352BhcEjih2QK1oR1HMlqk\",\"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\":1776114946514},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjExNjQ0NiwiaWF0IjoxNzc2MTEzMTQ2LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiJmZjY1ZTFhMy05MTA0LTQxNjItYTc4NS0yOWYzY2JkNzgwOTQiLCJhdF9oYXNoIjoiM2d5NEJCNk0tSEY5Z3NWd0ZMOFNqdyJ9.FS8zk7aSd1cheJGsRFszaQkbHIQBdm_1h8EB9ObjbZLo1w1amR7HMM-e2eLn_bv7mYZVIxV4NWHzqYZi19HVKFbuMkUDBQ1r9xEuwFIv7LmjvlTttBiXg6GAHCqWsXxV0_yN6y91ISG4dy3FKAWdd8Y9L-rIjRc6p5w8m1zdG-rnq4cO2O-uCOfRNMse_r7kYW5WY1IY3bKOvO_gi3ySwzZAtPI-PFWoEpy3PszeM_d343B_ZR-2wsmX5sZeyZP-ma_VYVktKVpVfm0mr6SZnCC9MpdUn1eKTpX2tyM-jm9_LZlOGkU8ClaRRMyFEH5SX5G_Q1ONyVAu5EEoYolp-Q\"},\"dpopKeyThumbprint\":\"8LW6CUuNAsgCC2G2M4XmoieSP8kcaatZLfqvyDQtVXQ\",\"issuedAtEpochMs\":1776113147515,\"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\":1776113146000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" + ], + [ + "stellaops:wasEverAuth", + "true" + ] + ] + }, + "events": { + "consoleErrors": [ + "Failed to load resource: the server responded with a status of 503 ()", + "Failed to load resource: the server responded with a status of 503 ()", + "Failed to load resource: the server responded with a status of 503 ()", + "Failed to load resource: the server responded with a status of 503 ()" + ], + "requestFailures": [], + "responseErrors": [ + { + "status": 503, + "method": "GET", + "url": "https://stella-ops.local/api/v1/scheduler/doctor/trends/categories/security?from=2025-04-18T20:45:47.536Z&to=2026-04-13T20:45:47.536Z", + "page": "https://stella-ops.local/" + }, + { + "status": 503, + "method": "GET", + "url": "https://stella-ops.local/api/v1/scheduler/doctor/trends/categories/platform?from=2025-04-18T20:45:47.536Z&to=2026-04-13T20:45:47.536Z", + "page": "https://stella-ops.local/" + }, + { + "status": 503, + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "page": "https://stella-ops.local/" + }, + { + "status": 503, + "method": "GET", + "url": "https://stella-ops.local/api/v1/vulnerabilities/status", + "page": "https://stella-ops.local/" + } + ] + }, + "statePath": "C:\\dev\\New folder\\git.stella-ops.org\\src\\Web\\StellaOps.Web\\output\\playwright\\live-release-environments.state.json" +} diff --git a/src/Web/StellaOps.Web/output/playwright/live-release-environments.state.json b/src/Web/StellaOps.Web/output/playwright/live-release-environments.state.json new file mode 100644 index 000000000..4e6c6f682 --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-release-environments.state.json @@ -0,0 +1,38 @@ +{ + "cookies": [], + "origins": [ + { + "origin": "https://stella-ops.local", + "localStorage": [ + { + "name": "stellaops.auth.session.full", + "value": "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjExNDk0NiwiaWF0IjoxNzc2MTEzMTQ2LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiNWNlMGUwNjItOWE4Zi00MjBjLWJjMjgtMWY1YTU0ZmEzMDA5Iiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMTMxNDYsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.iRgTzRk-RTHOTl6v4R8NqLXW9W-0WHkNdvDpDGhhJKJDZ6s0JygHiralN5oX_c-2DXZwihAYtefR5YnaBOgDzLmPmp8WN8V7J3BebrkInEfHDwT6JuTlNECXbWqs3JRJR6qzBat3qE335cyfKIIjPW7jGhqaHWZUs0EwFV0cTljn-M-BXztVlB7ixWHqEk-JeYiLJ2he58zhmU0LZX9imk800i3IGFjd6O2NyVbAtXshUJ2DauN28Yv-FdAXn3l6Q2r0zyrfOzburgd7ob-ewzaT6qCS3ccs8wRKSA7MqJ0FV_yfP6j10yjSmUpWfX-LHr4DpiktQvXtOLBSlRNZ_w\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.K7sT2dR_vyCjOiDRfxHPkmm5KmK2UTKqjLngPZvp_nUKwz4b7-RMHzeDmq1gXSSWwqfIB4Q_eg75XR87Mn_efjUvcoksDB1qwWFmTqA4-mTqIekMDf0-ng364HlgD82lu9_8XznzjC_NHvRW7569BPieAeel0ujFdNinq6jGHdgE98Lfb1Pt4_4h0rRVud-vsxxUBIMdI8nUzPjg_qAFdrBxf16CnAS58lU3Km7mheZl-bAmI6ke5zQU1AWPv9xBApeFtdWBLcVXtwtXLb_7VkVDXNs_dPoBCO6rIgOXZSwHa77KCyQhsL8a6lN9EuJ7BZwruDllo6NiObJEgglKmA.s_URdF4yamP_LlT8fBpXZQ.M4Hzmb0obrv4ahq6AKsrT2ilWkzBes5SmWeYkej3_33eTKExxBYIAB0XlJx2FEu58P2SvRrtdkOla92vcnBChJCInREFFXpNZCswIBqK0DB6caw_bDMGhlLp97nJf-xNiESsLSik88-puuSp1J0I4vhrgDyuJq04B32uWlj1YUkxV5ANDwzK3hPRRM7qarz7M5MpbzFRhsnF7Qd4i8ClD04IPRFui_Syy7N5wRyhvVUm8ZQgEa_8jobA6Jfi298_mvyi8gRjEq5P1jNOiuP0WW_txQ8Uqiafnu_LrRAYCW9XpFL7QoRXt2iB3jt3G7c7mqxI5WfvZCmmZhxHbTDp4o4PBAiX-e1LQIXqoUKRlDr7Gy8PPdOGLK66OJtL0uaCTwRQuWG2eBeFzdEgUQeGLcDyO7CZPFewPHgpCHQuHspA5RwfXgH9zI_4UxPQud8L1-5u5PduWAvH_4yw9TRl78pZxxPtBT0zQNz4RZOc2xRHie9WLsWzrogL6dSxSth3kgK4Yy_SIdJ65BL5zp-h1komXRhpfWlFxjMGsMMMlmjeCHwuQSwHNa8nZhBw7O8QaJ7kxwyQx-e6V13120MNCjlTsEoEIIIk6BAVlHDxGz9p_feRFoAo8jo5pG4BfKlQVZxRiaLH4xtmPxktVSQPy-zywJzb_43d5xwLY_fxdRa787HmwXizS2Ee_mqU32Sy8uzNi5qgwPoLSbJu4urbPzXjOAf58mU1ifvXWGmS6JLOR_vXJZ3q-zLt--9vXQl4LIg4SWgNSmyO1JpxL8s9K7lPTsG023dWB3cWA8hnQoqt5iNHjypkPxJJhXgS1O43JSZ5KHN1Y9QHvbobv2Fb-SfEYtqxLiVi9bh0_p9cU0NKm5a-QxWyIwqx-1RSuJYYM8nxjvilEPuBLYT1u8DCGxkkxg6WJz3wooQWM_XFs79H4VeV1yR3PmB5JxSxqEhprv6QxAX1y5KPRuLMCrGkrATtYvLfbg8yWThC_dK1hC3Y6Vwt9gnVDfWuHPp18yswiuWB-CdaMd3NGll7Qrl4CgLBycUXTQRZ-qMzW0I8cMrtvDozc1KjK073vRUOJvCS1rqm5C-f42ECE6NsNkdbAIQWjFOTCV8S9zJ6bunHKUdT9WH6UU9MOUBQXD7PmUYowPQ9JS-oG1YHwUFB9JfFZ6fcdYyqAcLd1_STg5_vOIv9ln457zpxoJykRd-95HJiHflD53-w2rcbkgdlC8_dJD6qxSUpy3hKd3k6U65DoU-WDuacvqq6514eztcV4ktLIfyij7YS-ZuCrFYyy7y0Di9EOEqSAXcFyqGumgT5Vra_GE4Nl6_O0sePmKV-4NA0l0LF7Hp-9xEmCIu1TONmyYpTr4oDrAMbIE9rnIBhe6ThGYy5qudj3LaKuHG3hgJgdC27m3qUNTEYpids-IYhsNgqNIGDnuI8ypyIBw_hVJnDe59N3LxpIH81j0K-_Gp8DLQqpSC-LhgMp8IZgz-dAi3OhpCAk-dC77lkNfFPyI8MdRV-2JMxw33sDQXoO-q8K6PfeLcxqf-d187OyC3cffSSTixyGRSvkNP71MGW3vGqTs8A74RNo6MR_RvZqQCEArAZaJUkvV2VsO73MEHWgrc2_xezdnFilvUB3d7nk28X_LjemwQfz1uB7rEkXqmQgo8huBBQ5cXY41oe8qalPthWphaEaNmSFIfD0tXGDesgmyN3ErEctXWyfZ_p3Gn6cL5G38JEQGEROvCJlmN8Oo3Ntbs2jy3ekGow72xsGGDfD9tKfwZWp13J18ewS8DKq1RpEV1pdaconBVYY34v9H8Tt1LIc_HxocfYHL2-7LYHStMIOYv8ftJ6aQ6TyIWtTTjKXdLjNVIlN7v4S-yxJItlmHdSFycQ8FuZDFvzwmhQ8yir3ES2TRWdIgO30bBrjQggfjPjvIs6m2ZWv3Aejv6cvbnonAUAqpQxCb2AYT5DNcKXxccLRJNaIOKCUjRIq97sp02fOSQT4zlN48ExqJoploFYBJNgs17k6nWwpIFwz0cdGP0zSu9CeLF6nZn4yfNs2p72T3uY4riuA5KCUYGr62ZW6r-jcE29SSBq5WPKwaWuTjT9NwQbFDzu0YXdq4jrg5OrGZp7cY5XMDuQmuX3Z7PvbfVlGmyjuuwIF1x4ZWRLkRbWfhvz6oBpAXp4VCKKvfwXV1xh1zyRSzBSAN4VMtcU6-a7ZR4Z8kh9yitLFPx8sRFWbCrbOy6AZqlio8gcPJxVbExny8A_Znt4E8ehxcoR-vDinmmCE1MedOThid4rFYWjZNEIStS5XeZI44jHlIuZeDfGTsxbDoXWEPDWh9WSSbp_JVyySyUNjL2hO7lcvm-MeslTlWsVgOPoY5vgvPmxges3P6DAoDFLecoCvrLh1ljxe30hqmMQqeZKq_UxoUd-1-lKWHjLuJAhg7L8q1y1JgHan45fZxb8jg_EP16AwPkkoONizFYLu78LDNWSZusYeYpsr2RM6YzDl1GYgYOf1LUl0BJ2nQU8ypzqziYRv8mJPOpYX10uLntygO0Kz_i4lU7xPI3w_yPAsCzcuwFsgZ1y2GpRwUAYMyhTYM9k2f96SJ4FAtFiiJKbD9QX3PzCcV794TKkrOO3Jl3kLBAN6pGByeOySJNZcgVS00NDw8SZ6zSWjLmD_rvWv6y_md2d4C8vqAs2SfPSUqO31HWaeOPuc-OeyeVBWt169jiE6F1MlZYbBOV8p-zBQ1zUq9fDIbi-wBdtnMqv52OvubOXz1hkOkAA7VzroqMyAmRx98FHYy6qzI4wZKjyKN4laez2FZLqBUqbEnxexhfvYYAnqqKtz35lktX0G-i9NAWSS_73WTsDlG4o20tGb8T6lrqIiscwWlxd_IxrC6g8lsLDc0pySr9vGYMVzAvFoEiVRwMMoAy7J81VcYaYwwwLNGY6gElCSfwcpudx8-46wJFGUYEhMe4-5Z3dt91HTbWXDBVY28fGnClubwCs-Ge1BQHbcekM_sBNCt00VpWeJx9TYrUtCP6w4-GX3h_8XQI65GnaEsZFpUzeNpd6hBLCW2GDr5CxJgefAvp0a2Hp4IxQWR6NSPp-VR7MTKbcb1ZUUKniEa4ZFL9VKI4Ovo06F0Ue2L_47EcSXzsn4RSSKjuTq-0ftsuoKXozV5m5q--BaBqNS4nfTz5NEE2TWCRMIRSCo1u_BZT_jRx7bDdswwZGK81m-ZqLcRV3fDr0HgGENVZkBbtRJYmn6FpqH9-6PyRvPSOyyX6MyaRAzIjWVMfP3ZBxbvcTRl_71fhCGHCgNsZ5GjHprcynMLsZg9bpttCmwVAVZUK0wOEFqlVgXt71LkiCSGEt1ISR1siQwaIxQ7LjG8tfwjBtkwJjNKc-hgBkiHh7MDJGgAAApr3gIV8EOaJi7_A7L4Bgo7UIJT8b1YSuXAqr0tMShuQ80FRVk1ravJHA2XpKJCsah3eJz7DCOWt11P69m_xjRCSZg6GI3-uCH6sU7SrtfZL6G7ZzrLpOENIb3AoAlmXJXPfIB8WWO8U_ygAcc5BA7-ZmNaFzeFTSTdBQHPSD278qM6L85DG-OFKIobVH8sMWnc6ZY9OV23s352N7CTtRf3E4OxEgpXozR6zBc-n1cXMEiVi0RdzBWWBFvfRCgAyyQLFAXKAXY6wlm07u9kA4S8ANrV1yYhLZdvVaLY2k0ThktrcvVDQ7wzqKNU3jKkkHwP_dTmLz-PtzZaaJla8IEn9suThrS-OMYKMYFHRBs71fUIwyP7vomhObrOd8X5GsWiXI2bIa3gNcfCVAw76K6LuEVc-3RqJ8LO4PaD9hoWl7YMbsv2iJXVlaBNJIJPR_2_3ZJYLssekYL_6SDnUrs4g-QXcLvY30cPQ1ICCx90hn38pYJOgeMWHrDEAuTgQMN0hA7ynoFgDx-_VVFORn0HiidM1Eh0Vp1oMdzfFPjerQJ65KhRO5TVEARQ7zosxjMMSXcq7LgEoqmtFNMDOeG-p8HR4pK_5aldcjBPxO29I-G58JivOfXvT-JblOzHj7hascqtGKpPdYZipB41iQVzFyVO0CL4hYVOa9Rvr-Vfk2unXgizTZaXFtnDwi8Km3Q4qVjJsQxDTPW9HgzxhqvRX9mW3QZMpsR_msPby46Tp-aOcEwVJcgviVIbdiFb3jPzRx7WpdKVY56tqeyqDtUherMMe_u42xMVEBZmvByLcjMyLZZUkQNAAgsaHazofZX3EDFTv-gXLJAZFvYJW4RS9fC6RpYlCzfaYNTI2WRvYzmIxebf8MNAH2Y-FVcWCAsGZB_z9ZCApfIAxbzEQqItFmWxEZqHB7qUbleZcYE_LTm7sNlUDOmF3VeW7qyspVOfSnT7N_mqW8TkZZ1SdaT2YcjLVjIvxTjQIjVbcsq52MA39UelR5ea8NkhSXv-u58YtQ7y8VHC_FeH7GErDJkc6HIE1q7PJ2IK-UtkwktY8NJWbEudNeRQsWG2n7mls9b2i-18NtyHk63v_FdUVXodAXa6oisKn_antJXcxRiLeMOHy7ooMDSV583oS3_ri2bZn31TO2cOsfUL4ffyOJSjHXgra5V6H2HNc_LNKo4QIJTaIHNreId0WA3lhCRy8fjaqb2-8jESQWqeQETfXEGf0NDIwG7LQ0MXaCAOiqdCIjN8DycCinIS_kWMW0WwfBujOkj7aPUH01JhtUdE9FDbwdD_sT1V2uUxJOwKY5voZrlI8_cD0kipY_E-NdiotJwF-A95gc0go9_6OSBxOWcQ.N9axeExjDktt2OgN_bzhv352BhcEjih2QK1oR1HMlqk\",\"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\":1776114946514},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjExNjQ0NiwiaWF0IjoxNzc2MTEzMTQ2LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiJmZjY1ZTFhMy05MTA0LTQxNjItYTc4NS0yOWYzY2JkNzgwOTQiLCJhdF9oYXNoIjoiM2d5NEJCNk0tSEY5Z3NWd0ZMOFNqdyJ9.FS8zk7aSd1cheJGsRFszaQkbHIQBdm_1h8EB9ObjbZLo1w1amR7HMM-e2eLn_bv7mYZVIxV4NWHzqYZi19HVKFbuMkUDBQ1r9xEuwFIv7LmjvlTttBiXg6GAHCqWsXxV0_yN6y91ISG4dy3FKAWdd8Y9L-rIjRc6p5w8m1zdG-rnq4cO2O-uCOfRNMse_r7kYW5WY1IY3bKOvO_gi3ySwzZAtPI-PFWoEpy3PszeM_d343B_ZR-2wsmX5sZeyZP-ma_VYVktKVpVfm0mr6SZnCC9MpdUn1eKTpX2tyM-jm9_LZlOGkU8ClaRRMyFEH5SX5G_Q1ONyVAu5EEoYolp-Q\"},\"dpopKeyThumbprint\":\"8LW6CUuNAsgCC2G2M4XmoieSP8kcaatZLfqvyDQtVXQ\",\"issuedAtEpochMs\":1776113147515,\"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\":1776113146000,\"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}" + }, + { + "name": "stellaops.theme", + "value": "system" + }, + { + "name": "stellaops.auth.session.info", + "value": "{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"expiresAtEpochMs\":1776114946514,\"issuedAtEpochMs\":1776113147515,\"dpopKeyThumbprint\":\"8LW6CUuNAsgCC2G2M4XmoieSP8kcaatZLfqvyDQtVXQ\",\"tenantId\":\"demo-prod\"}" + }, + { + "name": "stellaops.sidebar.preferences", + "value": "{\"sidebarCollapsed\":false,\"collapsedGroups\":[\"evidence\",\"setup-admin\"],\"collapsedSections\":[]}" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-debug.auth.json b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-debug.auth.json new file mode 100644 index 000000000..2770089dd --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-debug.auth.json @@ -0,0 +1,85 @@ +{ + "authenticatedAtUtc": "2026-04-13T22:22:19.030Z", + "baseUrl": "https://stella-ops.local", + "finalUrl": "https://stella-ops.local/?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Dashboard - StellaOps", + "cookies": [], + "storage": { + "localStorageEntries": [ + [ + "stellaops.auth.session.full", + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyMDczNiwiaWF0IjoxNzc2MTE4OTM2LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiNDg1ZDZlZGYtMWRlOC00NmQ0LWE3M2EtNjlkNzBmMGIyOGZkIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMTg5MzUsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.p5e56T1fQ7JLPLfFrBajxRcLZUO5U0Xj10rl62CJotnaumtfwZYYOiI2x0lkYun14t9IBlRdGQ4UKweLpNhE1_OICvcuxHdeY-mVfGcj5RAhHgvZF7n24aE5h3Yb8zevXD8QWzP__PmU4Juxj4AaQmEgEtTe_qHlDYTT2NugdewRXb4yEkdLRPvx_RGaS-bPK-ST0m2yrA54Oh-EJfqpzYHswYxku2Z9ZvIveRykeiICQP13aBn_j-hEf5zzpOA27HQP-ras7IMHR5jiPCZEBcLtnbf1oLl-sbOH3_LTDWnCNBecphNyyTko8ywRXZv5cSIf8pOU_y2PT4rZl1Ej5g\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.OMbuL1Bv5IpjtGfqEc-GMqqL-VPRUcMXQWA3nAaFw-1HZFUCjq21p8iTo210L46saJb9gBQb2jkqpoWYBHDjWysUCXMOrSyceXUf2AJakdVN69QlhwEN-I2kCgjpufTvcZUSEBkKp4aiuL6RWThBGVF1NE2I66B9G2KLJfwzMMWKRS6Chh6fnKlCd5SozfOj3wxnA68uEBs63lzg3Nwi_KO7FImQH0XjCkJ8GVN8gqiJ1u9FNVIFdlX0DtQWr_Ucz9nq5HtIEJAbTsA7dpal9JhEUrsJVf5Tckx1GaSWYe5qcSWo8_rVGFQ9GaNhU2HpiT5SDXUIPK0U9335zmPN_w.ElnrK7v-Df5eoFCMkFQxtw.ASVpdMFDAiiaHLi-nSf0pDj-XtwhhwyQdJZUd9vUe3tja3C-8g6LXlFliv9hf_mBnz8TJbwcQvmqt0iGL7iP10HL7ZkQmNxToHHpUAHb5-hjXF_hPCsENnmQ5eZEekOAruK8Dv1WDth_Z1GgZZsIJ0NTiIY82KHBUC79DgX2VU0EclDpmTVZQR5iz_woXVXU4_Ts0fFr8OAV9ZVHT2sFJ0_8S8woSQu13xz3lE0gfK2w6WTebaswNmwKa9SmnIbDsl_bMRB0-wl-x9ZGwQ3F8dEIkaWHcEnokOIu2W4M3rQfk4yL8oDlKGKTG9fp-MAscx99dinx49Sph2PuVe3CAydNKJhG3HQt0qEA3USvsma21Q5S0aLoJ0mDkjfAI65MziX3a19_5JR141gSJkTyOSoajlrum0zukydysBGdtzWOAu9lLC15kt6APzWrTM9KuWXPunQGxDINckh7paiicjMq0VVXF-QyitkL-NHQWeI8uXszhcsTsoRxT5xuvE2QBkrcyKFgs-2DWTbHqmg5utuKfQjtWAYF0pugXSX1XUl2qiyu2n4GSNYEURiQgzwpl-d1ss70zxmg2v4ZuF96Zq2H3j3rm5riesZJ5RIdUkus6cyvmU4ye8GR2_CtLoEeiLHpAo1suNP_-eIi6tHj8pba3VRuqiFncKSWSjGfJKYHDErP9bQSvD7pyMIfEoDWx9lylREaUtF1NQRkB6TNBTONnJ4N5hj1z2RrykzIFFpRRW0JLwHeJkmZua13Qc1EM0lx_lM_LJwlYLmFX83nsIADXMiX_unDaUeMyMaaQztDhHuyiuirdgS_iQnKA37rPyHBFyPt586tuawNbAprycbXISmf_SFtxtOrxYC6_lhLIG6ja7lBTnm5Pv0CvhsE4OMulZ0qIQK4hSNP7clCANJvBpYmsqDwRatA4Phn4j8RLnocPR3JWOd5GzDmEZYP2fFEexJjuifDqS4JtfVBM3ROBj3nNo5ah-nSqjURn5080_rqbfo75rcfVnNek6jyUmMC1ozkk_1_YAt5sOHqxol5Cifo7R6gsNl1HSoKfDjeWmfPsKxMW8EByhe4t5eKe3bU7MAfp5a6D3JJ_Jedr6-4vPDrx3du3BoXWEx4ee7lxbnewi83ZQNunqkN7eSyBwl16r9_mqv4mkdCfMMer44L0o3gUxK_uDiJGGR7vO1qkCfrW-7YbCSRPeYfRpjsET2rZpfGrBNzdFvX5hh2SKB9nw66ElM4ErduLww67XFehdj9Li934EA-oEKEs9SfteUW43-5_0znKwmKrKEOLJzhzC-03hUukpSbOZHle5h2JGhPy5rMm5KgMh9zhrXGQzpp-3pHNd8HVmMCXy7RtYABQmmcgBNq7TwR3MTWb8Hi2ETkXzUK32Bq7dXuWbSZ7jcn9YbKdxxYbDyfw_99ShY8RPUVUHTsy_Qmtf4JhiZ2RkEq2QJn4wP3DB0ZqS2YsqcUNGhXAGdU9T6dMKNLWEvXR-VlvSF4kpG-04_MS1iv7JwG_FhcXa_GvrAs3myB9lMyXLLLaXQPJsKwwgji0vm-TBHLHSO3BHbjY_1b6H8ENrd6BXBc4POEoC2U6dt1Gqk90SSHRhQG4g0muV6PX-VF0FjF4ib58I0SzXsBU74epIr2wzDr0bo-w5NIxtj4jTQzq6LhJAck-6ieTHl5MEvarSlkDXEBJbI8zCUZ9KQtafSU-DHah_xvhf3Wwmw-x8dk4UBwyGHo_sdFOpHOn0t-4NZTli0WqHn552yqFERsrgZlbQw8UsQaH6Sn-td61Zj6glABpjnPpBMb1wludZaLe4QKejG8AN5QO-ro7njSL7mHoDks98nhGpjk62VltqLy0wLtWUoAdf7sMez7LS9ovfiHZEt8oSS8426hn7t0nWFmTAFt4485ctp0MZzmj9YMy_9f9iMCFNZi2ZswA3JzEc9oAwDxpMy1rWQH63lJRDgMXBb39z5t7GYliqcXVax1MYI6lm8J09qmVHECON6Q2N5KbQ2AAxMCP8gC4KqFa0avV-lS_8eM9piFTnM-GMo_nu--UdXbiDRhMgEu6Ky6bwX_89sr_0Y4H4DM3jwXfR_BxQNlqoF87ArFKSG4wIUO0uqiIzQYbuUet70NKMt0qYZqDzbLCZjGVOm5G8APNcqaNJWS38KSqmKZ5i7NtNKAoBPZeJYXUeqpmY5_tMli8m4vnXKOhhGdZ2jzk1lOP1OYHz2jrOPlwQu0BnueR-rWkaDovgIPiiFdtk694rbBDohcDFs6ljaMe5bQBJ2PFxN4ZfGEA_fDvwvnS8tUkAuzOGjPheuboDIQzxkVisPaQJn0Pgz0vD8LQSS5DzvGpVes3wVMkMMzHVAxY6kqvh3gRU8uojVMQhTO2a2PH55zJH-IdLi1yRSA5jtfWn-ORCzvVw_wuxQN-9K48vEHDYkM6ZIdERkQGfT-WM0dZq1JI5CEgAl3_H2C4rXUSWIIOpD_4SxLNuppBC-BtxvY2hXI826a7GOZsCmvL6OeWQGbyrlimbMelWdneKwsDNT8fI75ef9DK5YSOy6jHUEXnhppNdyRax1LJobjboeqsl5UKed0CCykEdJVutQ4H-n9nHJtXOW5f58NLPvF-5O5wnrUTA__AnfJXGnuXGwx-mIbGwOH-ygjw4utmxu4K8gU30_mDhCeDuJWr6XNFQz0JBqL7pL5lWkry06k8-MBb0YKDri0Z2822l8B9tj-6qL0BYdpMkhe8nvNcSAHzBaiY7fSpAuirgMWP4nYpsPdQbAveuY6CX8viIAzgcN8mAhE3JpopSF8_F2xySWvcXuejem5a0dJPaYn_WsEPBgT20acdBsbW0jjzDFgBYi4_6JKGeAYGppROgtFITHY6YgbRtT1xb1f5Y_ROVlCzuKMQCv5lq_-f10MAoWUUR8WkyrcM5hQEEKzRx2g9-OkV8ugdfBws6soS2S-e2_6THGDcKKPXrg2KbNSRBSn-ybJRwKgkcEHuEDImLFYQTroh-IHdAZHRUuAVoC4KvzkoxenyOs1HJuKrFf6sTJbvcw9URmS-6Z9liB7nuJVh3XI3PJ2CELGATgGxA3Y_t67nWhTKhDYf4Uto_e0sKr0lBv4IalObinGwEY0ieL5UYEZ6iDV_7ZBlaiHZJAPuPF54e5mpGO3YfOWqsoBiet1A4urTWKu-SUHpIfx8eweyxM5dehIUF3GJdjI08itKDQtZXi83wC9A4oVn-CBJgO04lpxZGXzZtLwqtgSaf5WTKvE1WdSFSwtofKqASFOkaNNovSk7HTWQMm8EBHE__4GjGO0ior4eeIGFb9oYexn7H60kniWpwssZzfUvM-f2oDI-aPIjkZwHWBzVAW8QJCqiJ9a61LGB5FKgxIA-x8YUeW0OW0gAHsWhtkxDbZjvd5CC4fl1HHAu2YH5zFx8pzj08rk3lC9UrfF4snNxsNc1eQRHo3XcqN7pZ3RFBsUgH4koiog7vlUoNKgtm51ySQKbLqXIMYYszVKAoRsVjRFr15AaA2ZMWWtRls2tsgQ3O1i5I5sgNN6_kBAlwgmVAs26NHbklopVv30ebDYtUmC-DR3PVtl5Ik4PsgjWpdKd6F-9LFf_tQDun5U4phhgT_JsK1hQA3Reu0irgd83-BVqGIhawFsh3tRbwBItCFUAk8nH-an5nSUM9K-fL087M0o2NQDaGSiaeE9YjwxOPJxcpVHGYR0xf4yVpi01hp7KvT2hZ_xZWVlJy5ZfTXzr2-32VbZQil2LpcpKE2SPGFqPM3DqUbXsJRKmxC-Tzkyax4ijIKe0Rk6KLIJ3oiG7s59KF-762vI2wat68-7deeqXN3WLJg0VJwIM0BJbMBtcBFlEx3b8fxZK_Mh_El6Zsd0vyyU7aXNFvkdDG80NnpUEdV49okFTQhMd_Mf4BhsHjN-T57kxcYw8zH-qfFYyB2lFSgZQ8sDvOH8-mApjHCNDCqybUZYiTaMdmpV6WR8E6N3BIAhkl3STLFUNXAojkPs98EfSzS-hg__O-YgwkIm8LzdMqPVdTp38YZ0ZhX2dQlR9djd67a0dw3fC830ETUC58c6wxz9iH_OSy1DJSb6DCi8k8SD_djtHAIb1DYeusljv0okoL3hLs74Xjv3wes3TkXq9QxikDZsuMdSqUvfg6nizhtqsHaPlntkknTittZc-i-YSWV1tFAPFmP_8KP_SyS5oL-cUY8JYv-JXXKbmjiMN0KieEjCJ5LNidG2gBGs5EZH80ZtVc2QhQm590DkdHDMSqhvzj7QjyHBEYK4bdBDheHVcex8odQ7K1OVvUA4VAPQYaY6ZMtI31bL1y1RXJ1pI7Q7yfrE_Z6F66uxcgPVmW0n97YfskoITSapfYpFDMAW-DOqQg3zIIrxhn43CBm5roy5qJ_pxpWtNPls9w9myLq5TDRbgVlJFyBbXcpkpCJWFz43uxZ9YO_KQe5OSsU72kzvdaK1SaUq5GqOLksagxCrCOf4vml9To2BECBo8j3o5cYHQ5NxPPehcmdpj_7720GKgth3tLTNoaEtWPXvXOtg4OqmvWJrVCMO57h1AAJIgKdlezrbmKRM9ZLqJtRfIdlWiHnfcjdAqauWcJrL33IXWu8wzaX9EqOeHPIbB0isp0RfqFYAjZ14Dce9fYUR9YRIvBEpXDZePIy4QX3CYDsvqpYYGvdMrXY4T7WI8usXlQ2snicdCxPZSOLYFjpIiPK0r-0j2zYnVuSwJNRE7tfuiaeaGtWVrM6IH7b3WxNMsg.y2jKuIAIL4f_ZVz_vXopzA-_vcI-gOlBLTjHtH16LRM\",\"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\":1776120736384},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyMjIzNiwiaWF0IjoxNzc2MTE4OTM2LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiJjNDkwOTBkNC0zZDU4LTRkM2YtYTgyOS1hMzQxNWIxZTUxZjYiLCJhdF9oYXNoIjoiTEtlRm1xWjF1QzY3VmpLYWtqNEpkdyJ9.j6qSw3k7CQ_gNphpdpBR8jRVo93NKMc1f9RM_xNgK7Q7a0CHEkTG9KU6yjwwd2ax4QCqt7ZUnntiVtY7vzYsL7m_iMNRw5KgWZsAxhayF63Wcf1SL-n_SFCkuwer2cn2IIKEUbZU6gjPOJXQFCsGSk4zKV1vBPfK58Xehwd0vqatbWeLAPf-wL5FdxmbBgXgsEwKr2VT5SvOJAhudwMT4OEcJU6jT9p0m_qQ_c0LeTk0G3DSY8rV6oyDkWl6aLLmsQ1emt9XFOqK5KCzQ3BLf-KeEAYE_3ChC9oG8ffeexdL1la_JnnnwPThP4OdpFM4VKocF3vgZE-dWDxttfm03Q\"},\"dpopKeyThumbprint\":\"tWbRqd-LVL_MhtGKggl8lgZo8HvAF3PcH-5vmA-xXHQ\",\"issuedAtEpochMs\":1776118936384,\"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\":1776118935000,\"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}" + ], + [ + "stellaops.theme", + "system" + ], + [ + "stellaops.auth.session.info", + "{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"expiresAtEpochMs\":1776120736384,\"issuedAtEpochMs\":1776118936384,\"dpopKeyThumbprint\":\"tWbRqd-LVL_MhtGKggl8lgZo8HvAF3PcH-5vmA-xXHQ\",\"tenantId\":\"demo-prod\"}" + ], + [ + "stellaops.sidebar.preferences", + "{\"sidebarCollapsed\":false,\"collapsedGroups\":[\"evidence\",\"setup-admin\"],\"collapsedSections\":[]}" + ] + ], + "sessionStorageEntries": [ + [ + "stellaops.auth.session.full", + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyMDczNiwiaWF0IjoxNzc2MTE4OTM2LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiNDg1ZDZlZGYtMWRlOC00NmQ0LWE3M2EtNjlkNzBmMGIyOGZkIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMTg5MzUsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.p5e56T1fQ7JLPLfFrBajxRcLZUO5U0Xj10rl62CJotnaumtfwZYYOiI2x0lkYun14t9IBlRdGQ4UKweLpNhE1_OICvcuxHdeY-mVfGcj5RAhHgvZF7n24aE5h3Yb8zevXD8QWzP__PmU4Juxj4AaQmEgEtTe_qHlDYTT2NugdewRXb4yEkdLRPvx_RGaS-bPK-ST0m2yrA54Oh-EJfqpzYHswYxku2Z9ZvIveRykeiICQP13aBn_j-hEf5zzpOA27HQP-ras7IMHR5jiPCZEBcLtnbf1oLl-sbOH3_LTDWnCNBecphNyyTko8ywRXZv5cSIf8pOU_y2PT4rZl1Ej5g\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.OMbuL1Bv5IpjtGfqEc-GMqqL-VPRUcMXQWA3nAaFw-1HZFUCjq21p8iTo210L46saJb9gBQb2jkqpoWYBHDjWysUCXMOrSyceXUf2AJakdVN69QlhwEN-I2kCgjpufTvcZUSEBkKp4aiuL6RWThBGVF1NE2I66B9G2KLJfwzMMWKRS6Chh6fnKlCd5SozfOj3wxnA68uEBs63lzg3Nwi_KO7FImQH0XjCkJ8GVN8gqiJ1u9FNVIFdlX0DtQWr_Ucz9nq5HtIEJAbTsA7dpal9JhEUrsJVf5Tckx1GaSWYe5qcSWo8_rVGFQ9GaNhU2HpiT5SDXUIPK0U9335zmPN_w.ElnrK7v-Df5eoFCMkFQxtw.ASVpdMFDAiiaHLi-nSf0pDj-XtwhhwyQdJZUd9vUe3tja3C-8g6LXlFliv9hf_mBnz8TJbwcQvmqt0iGL7iP10HL7ZkQmNxToHHpUAHb5-hjXF_hPCsENnmQ5eZEekOAruK8Dv1WDth_Z1GgZZsIJ0NTiIY82KHBUC79DgX2VU0EclDpmTVZQR5iz_woXVXU4_Ts0fFr8OAV9ZVHT2sFJ0_8S8woSQu13xz3lE0gfK2w6WTebaswNmwKa9SmnIbDsl_bMRB0-wl-x9ZGwQ3F8dEIkaWHcEnokOIu2W4M3rQfk4yL8oDlKGKTG9fp-MAscx99dinx49Sph2PuVe3CAydNKJhG3HQt0qEA3USvsma21Q5S0aLoJ0mDkjfAI65MziX3a19_5JR141gSJkTyOSoajlrum0zukydysBGdtzWOAu9lLC15kt6APzWrTM9KuWXPunQGxDINckh7paiicjMq0VVXF-QyitkL-NHQWeI8uXszhcsTsoRxT5xuvE2QBkrcyKFgs-2DWTbHqmg5utuKfQjtWAYF0pugXSX1XUl2qiyu2n4GSNYEURiQgzwpl-d1ss70zxmg2v4ZuF96Zq2H3j3rm5riesZJ5RIdUkus6cyvmU4ye8GR2_CtLoEeiLHpAo1suNP_-eIi6tHj8pba3VRuqiFncKSWSjGfJKYHDErP9bQSvD7pyMIfEoDWx9lylREaUtF1NQRkB6TNBTONnJ4N5hj1z2RrykzIFFpRRW0JLwHeJkmZua13Qc1EM0lx_lM_LJwlYLmFX83nsIADXMiX_unDaUeMyMaaQztDhHuyiuirdgS_iQnKA37rPyHBFyPt586tuawNbAprycbXISmf_SFtxtOrxYC6_lhLIG6ja7lBTnm5Pv0CvhsE4OMulZ0qIQK4hSNP7clCANJvBpYmsqDwRatA4Phn4j8RLnocPR3JWOd5GzDmEZYP2fFEexJjuifDqS4JtfVBM3ROBj3nNo5ah-nSqjURn5080_rqbfo75rcfVnNek6jyUmMC1ozkk_1_YAt5sOHqxol5Cifo7R6gsNl1HSoKfDjeWmfPsKxMW8EByhe4t5eKe3bU7MAfp5a6D3JJ_Jedr6-4vPDrx3du3BoXWEx4ee7lxbnewi83ZQNunqkN7eSyBwl16r9_mqv4mkdCfMMer44L0o3gUxK_uDiJGGR7vO1qkCfrW-7YbCSRPeYfRpjsET2rZpfGrBNzdFvX5hh2SKB9nw66ElM4ErduLww67XFehdj9Li934EA-oEKEs9SfteUW43-5_0znKwmKrKEOLJzhzC-03hUukpSbOZHle5h2JGhPy5rMm5KgMh9zhrXGQzpp-3pHNd8HVmMCXy7RtYABQmmcgBNq7TwR3MTWb8Hi2ETkXzUK32Bq7dXuWbSZ7jcn9YbKdxxYbDyfw_99ShY8RPUVUHTsy_Qmtf4JhiZ2RkEq2QJn4wP3DB0ZqS2YsqcUNGhXAGdU9T6dMKNLWEvXR-VlvSF4kpG-04_MS1iv7JwG_FhcXa_GvrAs3myB9lMyXLLLaXQPJsKwwgji0vm-TBHLHSO3BHbjY_1b6H8ENrd6BXBc4POEoC2U6dt1Gqk90SSHRhQG4g0muV6PX-VF0FjF4ib58I0SzXsBU74epIr2wzDr0bo-w5NIxtj4jTQzq6LhJAck-6ieTHl5MEvarSlkDXEBJbI8zCUZ9KQtafSU-DHah_xvhf3Wwmw-x8dk4UBwyGHo_sdFOpHOn0t-4NZTli0WqHn552yqFERsrgZlbQw8UsQaH6Sn-td61Zj6glABpjnPpBMb1wludZaLe4QKejG8AN5QO-ro7njSL7mHoDks98nhGpjk62VltqLy0wLtWUoAdf7sMez7LS9ovfiHZEt8oSS8426hn7t0nWFmTAFt4485ctp0MZzmj9YMy_9f9iMCFNZi2ZswA3JzEc9oAwDxpMy1rWQH63lJRDgMXBb39z5t7GYliqcXVax1MYI6lm8J09qmVHECON6Q2N5KbQ2AAxMCP8gC4KqFa0avV-lS_8eM9piFTnM-GMo_nu--UdXbiDRhMgEu6Ky6bwX_89sr_0Y4H4DM3jwXfR_BxQNlqoF87ArFKSG4wIUO0uqiIzQYbuUet70NKMt0qYZqDzbLCZjGVOm5G8APNcqaNJWS38KSqmKZ5i7NtNKAoBPZeJYXUeqpmY5_tMli8m4vnXKOhhGdZ2jzk1lOP1OYHz2jrOPlwQu0BnueR-rWkaDovgIPiiFdtk694rbBDohcDFs6ljaMe5bQBJ2PFxN4ZfGEA_fDvwvnS8tUkAuzOGjPheuboDIQzxkVisPaQJn0Pgz0vD8LQSS5DzvGpVes3wVMkMMzHVAxY6kqvh3gRU8uojVMQhTO2a2PH55zJH-IdLi1yRSA5jtfWn-ORCzvVw_wuxQN-9K48vEHDYkM6ZIdERkQGfT-WM0dZq1JI5CEgAl3_H2C4rXUSWIIOpD_4SxLNuppBC-BtxvY2hXI826a7GOZsCmvL6OeWQGbyrlimbMelWdneKwsDNT8fI75ef9DK5YSOy6jHUEXnhppNdyRax1LJobjboeqsl5UKed0CCykEdJVutQ4H-n9nHJtXOW5f58NLPvF-5O5wnrUTA__AnfJXGnuXGwx-mIbGwOH-ygjw4utmxu4K8gU30_mDhCeDuJWr6XNFQz0JBqL7pL5lWkry06k8-MBb0YKDri0Z2822l8B9tj-6qL0BYdpMkhe8nvNcSAHzBaiY7fSpAuirgMWP4nYpsPdQbAveuY6CX8viIAzgcN8mAhE3JpopSF8_F2xySWvcXuejem5a0dJPaYn_WsEPBgT20acdBsbW0jjzDFgBYi4_6JKGeAYGppROgtFITHY6YgbRtT1xb1f5Y_ROVlCzuKMQCv5lq_-f10MAoWUUR8WkyrcM5hQEEKzRx2g9-OkV8ugdfBws6soS2S-e2_6THGDcKKPXrg2KbNSRBSn-ybJRwKgkcEHuEDImLFYQTroh-IHdAZHRUuAVoC4KvzkoxenyOs1HJuKrFf6sTJbvcw9URmS-6Z9liB7nuJVh3XI3PJ2CELGATgGxA3Y_t67nWhTKhDYf4Uto_e0sKr0lBv4IalObinGwEY0ieL5UYEZ6iDV_7ZBlaiHZJAPuPF54e5mpGO3YfOWqsoBiet1A4urTWKu-SUHpIfx8eweyxM5dehIUF3GJdjI08itKDQtZXi83wC9A4oVn-CBJgO04lpxZGXzZtLwqtgSaf5WTKvE1WdSFSwtofKqASFOkaNNovSk7HTWQMm8EBHE__4GjGO0ior4eeIGFb9oYexn7H60kniWpwssZzfUvM-f2oDI-aPIjkZwHWBzVAW8QJCqiJ9a61LGB5FKgxIA-x8YUeW0OW0gAHsWhtkxDbZjvd5CC4fl1HHAu2YH5zFx8pzj08rk3lC9UrfF4snNxsNc1eQRHo3XcqN7pZ3RFBsUgH4koiog7vlUoNKgtm51ySQKbLqXIMYYszVKAoRsVjRFr15AaA2ZMWWtRls2tsgQ3O1i5I5sgNN6_kBAlwgmVAs26NHbklopVv30ebDYtUmC-DR3PVtl5Ik4PsgjWpdKd6F-9LFf_tQDun5U4phhgT_JsK1hQA3Reu0irgd83-BVqGIhawFsh3tRbwBItCFUAk8nH-an5nSUM9K-fL087M0o2NQDaGSiaeE9YjwxOPJxcpVHGYR0xf4yVpi01hp7KvT2hZ_xZWVlJy5ZfTXzr2-32VbZQil2LpcpKE2SPGFqPM3DqUbXsJRKmxC-Tzkyax4ijIKe0Rk6KLIJ3oiG7s59KF-762vI2wat68-7deeqXN3WLJg0VJwIM0BJbMBtcBFlEx3b8fxZK_Mh_El6Zsd0vyyU7aXNFvkdDG80NnpUEdV49okFTQhMd_Mf4BhsHjN-T57kxcYw8zH-qfFYyB2lFSgZQ8sDvOH8-mApjHCNDCqybUZYiTaMdmpV6WR8E6N3BIAhkl3STLFUNXAojkPs98EfSzS-hg__O-YgwkIm8LzdMqPVdTp38YZ0ZhX2dQlR9djd67a0dw3fC830ETUC58c6wxz9iH_OSy1DJSb6DCi8k8SD_djtHAIb1DYeusljv0okoL3hLs74Xjv3wes3TkXq9QxikDZsuMdSqUvfg6nizhtqsHaPlntkknTittZc-i-YSWV1tFAPFmP_8KP_SyS5oL-cUY8JYv-JXXKbmjiMN0KieEjCJ5LNidG2gBGs5EZH80ZtVc2QhQm590DkdHDMSqhvzj7QjyHBEYK4bdBDheHVcex8odQ7K1OVvUA4VAPQYaY6ZMtI31bL1y1RXJ1pI7Q7yfrE_Z6F66uxcgPVmW0n97YfskoITSapfYpFDMAW-DOqQg3zIIrxhn43CBm5roy5qJ_pxpWtNPls9w9myLq5TDRbgVlJFyBbXcpkpCJWFz43uxZ9YO_KQe5OSsU72kzvdaK1SaUq5GqOLksagxCrCOf4vml9To2BECBo8j3o5cYHQ5NxPPehcmdpj_7720GKgth3tLTNoaEtWPXvXOtg4OqmvWJrVCMO57h1AAJIgKdlezrbmKRM9ZLqJtRfIdlWiHnfcjdAqauWcJrL33IXWu8wzaX9EqOeHPIbB0isp0RfqFYAjZ14Dce9fYUR9YRIvBEpXDZePIy4QX3CYDsvqpYYGvdMrXY4T7WI8usXlQ2snicdCxPZSOLYFjpIiPK0r-0j2zYnVuSwJNRE7tfuiaeaGtWVrM6IH7b3WxNMsg.y2jKuIAIL4f_ZVz_vXopzA-_vcI-gOlBLTjHtH16LRM\",\"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\":1776120736384},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyMjIzNiwiaWF0IjoxNzc2MTE4OTM2LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiJjNDkwOTBkNC0zZDU4LTRkM2YtYTgyOS1hMzQxNWIxZTUxZjYiLCJhdF9oYXNoIjoiTEtlRm1xWjF1QzY3VmpLYWtqNEpkdyJ9.j6qSw3k7CQ_gNphpdpBR8jRVo93NKMc1f9RM_xNgK7Q7a0CHEkTG9KU6yjwwd2ax4QCqt7ZUnntiVtY7vzYsL7m_iMNRw5KgWZsAxhayF63Wcf1SL-n_SFCkuwer2cn2IIKEUbZU6gjPOJXQFCsGSk4zKV1vBPfK58Xehwd0vqatbWeLAPf-wL5FdxmbBgXgsEwKr2VT5SvOJAhudwMT4OEcJU6jT9p0m_qQ_c0LeTk0G3DSY8rV6oyDkWl6aLLmsQ1emt9XFOqK5KCzQ3BLf-KeEAYE_3ChC9oG8ffeexdL1la_JnnnwPThP4OdpFM4VKocF3vgZE-dWDxttfm03Q\"},\"dpopKeyThumbprint\":\"tWbRqd-LVL_MhtGKggl8lgZo8HvAF3PcH-5vmA-xXHQ\",\"issuedAtEpochMs\":1776118936384,\"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\":1776118935000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" + ], + [ + "stellaops:wasEverAuth", + "true" + ] + ] + }, + "events": { + "consoleErrors": [ + "Failed to load resource: the server responded with a status of 503 ()", + "Failed to load resource: the server responded with a status of 503 ()", + "Failed to load resource: the server responded with a status of 503 ()", + "Failed to load resource: the server responded with a status of 503 ()" + ], + "requestFailures": [], + "responseErrors": [ + { + "status": 503, + "method": "GET", + "url": "https://stella-ops.local/api/v1/scheduler/doctor/trends/categories/security?from=2025-04-18T22:22:16.416Z&to=2026-04-13T22:22:16.416Z", + "page": "https://stella-ops.local/" + }, + { + "status": 503, + "method": "GET", + "url": "https://stella-ops.local/api/v1/scheduler/doctor/trends/categories/platform?from=2025-04-18T22:22:16.416Z&to=2026-04-13T22:22:16.416Z", + "page": "https://stella-ops.local/" + }, + { + "status": 503, + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "page": "https://stella-ops.local/" + }, + { + "status": 503, + "method": "GET", + "url": "https://stella-ops.local/api/v1/vulnerabilities/status", + "page": "https://stella-ops.local/" + } + ] + }, + "statePath": "src/Web/StellaOps.Web/output/playwright/live-setup-wizard-debug.state.json" +} diff --git a/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-debug.state.json b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-debug.state.json new file mode 100644 index 000000000..cf3ab5afa --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-debug.state.json @@ -0,0 +1,38 @@ +{ + "cookies": [], + "origins": [ + { + "origin": "https://stella-ops.local", + "localStorage": [ + { + "name": "stellaops.auth.session.full", + "value": "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyMDczNiwiaWF0IjoxNzc2MTE4OTM2LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiNDg1ZDZlZGYtMWRlOC00NmQ0LWE3M2EtNjlkNzBmMGIyOGZkIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMTg5MzUsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.p5e56T1fQ7JLPLfFrBajxRcLZUO5U0Xj10rl62CJotnaumtfwZYYOiI2x0lkYun14t9IBlRdGQ4UKweLpNhE1_OICvcuxHdeY-mVfGcj5RAhHgvZF7n24aE5h3Yb8zevXD8QWzP__PmU4Juxj4AaQmEgEtTe_qHlDYTT2NugdewRXb4yEkdLRPvx_RGaS-bPK-ST0m2yrA54Oh-EJfqpzYHswYxku2Z9ZvIveRykeiICQP13aBn_j-hEf5zzpOA27HQP-ras7IMHR5jiPCZEBcLtnbf1oLl-sbOH3_LTDWnCNBecphNyyTko8ywRXZv5cSIf8pOU_y2PT4rZl1Ej5g\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.OMbuL1Bv5IpjtGfqEc-GMqqL-VPRUcMXQWA3nAaFw-1HZFUCjq21p8iTo210L46saJb9gBQb2jkqpoWYBHDjWysUCXMOrSyceXUf2AJakdVN69QlhwEN-I2kCgjpufTvcZUSEBkKp4aiuL6RWThBGVF1NE2I66B9G2KLJfwzMMWKRS6Chh6fnKlCd5SozfOj3wxnA68uEBs63lzg3Nwi_KO7FImQH0XjCkJ8GVN8gqiJ1u9FNVIFdlX0DtQWr_Ucz9nq5HtIEJAbTsA7dpal9JhEUrsJVf5Tckx1GaSWYe5qcSWo8_rVGFQ9GaNhU2HpiT5SDXUIPK0U9335zmPN_w.ElnrK7v-Df5eoFCMkFQxtw.ASVpdMFDAiiaHLi-nSf0pDj-XtwhhwyQdJZUd9vUe3tja3C-8g6LXlFliv9hf_mBnz8TJbwcQvmqt0iGL7iP10HL7ZkQmNxToHHpUAHb5-hjXF_hPCsENnmQ5eZEekOAruK8Dv1WDth_Z1GgZZsIJ0NTiIY82KHBUC79DgX2VU0EclDpmTVZQR5iz_woXVXU4_Ts0fFr8OAV9ZVHT2sFJ0_8S8woSQu13xz3lE0gfK2w6WTebaswNmwKa9SmnIbDsl_bMRB0-wl-x9ZGwQ3F8dEIkaWHcEnokOIu2W4M3rQfk4yL8oDlKGKTG9fp-MAscx99dinx49Sph2PuVe3CAydNKJhG3HQt0qEA3USvsma21Q5S0aLoJ0mDkjfAI65MziX3a19_5JR141gSJkTyOSoajlrum0zukydysBGdtzWOAu9lLC15kt6APzWrTM9KuWXPunQGxDINckh7paiicjMq0VVXF-QyitkL-NHQWeI8uXszhcsTsoRxT5xuvE2QBkrcyKFgs-2DWTbHqmg5utuKfQjtWAYF0pugXSX1XUl2qiyu2n4GSNYEURiQgzwpl-d1ss70zxmg2v4ZuF96Zq2H3j3rm5riesZJ5RIdUkus6cyvmU4ye8GR2_CtLoEeiLHpAo1suNP_-eIi6tHj8pba3VRuqiFncKSWSjGfJKYHDErP9bQSvD7pyMIfEoDWx9lylREaUtF1NQRkB6TNBTONnJ4N5hj1z2RrykzIFFpRRW0JLwHeJkmZua13Qc1EM0lx_lM_LJwlYLmFX83nsIADXMiX_unDaUeMyMaaQztDhHuyiuirdgS_iQnKA37rPyHBFyPt586tuawNbAprycbXISmf_SFtxtOrxYC6_lhLIG6ja7lBTnm5Pv0CvhsE4OMulZ0qIQK4hSNP7clCANJvBpYmsqDwRatA4Phn4j8RLnocPR3JWOd5GzDmEZYP2fFEexJjuifDqS4JtfVBM3ROBj3nNo5ah-nSqjURn5080_rqbfo75rcfVnNek6jyUmMC1ozkk_1_YAt5sOHqxol5Cifo7R6gsNl1HSoKfDjeWmfPsKxMW8EByhe4t5eKe3bU7MAfp5a6D3JJ_Jedr6-4vPDrx3du3BoXWEx4ee7lxbnewi83ZQNunqkN7eSyBwl16r9_mqv4mkdCfMMer44L0o3gUxK_uDiJGGR7vO1qkCfrW-7YbCSRPeYfRpjsET2rZpfGrBNzdFvX5hh2SKB9nw66ElM4ErduLww67XFehdj9Li934EA-oEKEs9SfteUW43-5_0znKwmKrKEOLJzhzC-03hUukpSbOZHle5h2JGhPy5rMm5KgMh9zhrXGQzpp-3pHNd8HVmMCXy7RtYABQmmcgBNq7TwR3MTWb8Hi2ETkXzUK32Bq7dXuWbSZ7jcn9YbKdxxYbDyfw_99ShY8RPUVUHTsy_Qmtf4JhiZ2RkEq2QJn4wP3DB0ZqS2YsqcUNGhXAGdU9T6dMKNLWEvXR-VlvSF4kpG-04_MS1iv7JwG_FhcXa_GvrAs3myB9lMyXLLLaXQPJsKwwgji0vm-TBHLHSO3BHbjY_1b6H8ENrd6BXBc4POEoC2U6dt1Gqk90SSHRhQG4g0muV6PX-VF0FjF4ib58I0SzXsBU74epIr2wzDr0bo-w5NIxtj4jTQzq6LhJAck-6ieTHl5MEvarSlkDXEBJbI8zCUZ9KQtafSU-DHah_xvhf3Wwmw-x8dk4UBwyGHo_sdFOpHOn0t-4NZTli0WqHn552yqFERsrgZlbQw8UsQaH6Sn-td61Zj6glABpjnPpBMb1wludZaLe4QKejG8AN5QO-ro7njSL7mHoDks98nhGpjk62VltqLy0wLtWUoAdf7sMez7LS9ovfiHZEt8oSS8426hn7t0nWFmTAFt4485ctp0MZzmj9YMy_9f9iMCFNZi2ZswA3JzEc9oAwDxpMy1rWQH63lJRDgMXBb39z5t7GYliqcXVax1MYI6lm8J09qmVHECON6Q2N5KbQ2AAxMCP8gC4KqFa0avV-lS_8eM9piFTnM-GMo_nu--UdXbiDRhMgEu6Ky6bwX_89sr_0Y4H4DM3jwXfR_BxQNlqoF87ArFKSG4wIUO0uqiIzQYbuUet70NKMt0qYZqDzbLCZjGVOm5G8APNcqaNJWS38KSqmKZ5i7NtNKAoBPZeJYXUeqpmY5_tMli8m4vnXKOhhGdZ2jzk1lOP1OYHz2jrOPlwQu0BnueR-rWkaDovgIPiiFdtk694rbBDohcDFs6ljaMe5bQBJ2PFxN4ZfGEA_fDvwvnS8tUkAuzOGjPheuboDIQzxkVisPaQJn0Pgz0vD8LQSS5DzvGpVes3wVMkMMzHVAxY6kqvh3gRU8uojVMQhTO2a2PH55zJH-IdLi1yRSA5jtfWn-ORCzvVw_wuxQN-9K48vEHDYkM6ZIdERkQGfT-WM0dZq1JI5CEgAl3_H2C4rXUSWIIOpD_4SxLNuppBC-BtxvY2hXI826a7GOZsCmvL6OeWQGbyrlimbMelWdneKwsDNT8fI75ef9DK5YSOy6jHUEXnhppNdyRax1LJobjboeqsl5UKed0CCykEdJVutQ4H-n9nHJtXOW5f58NLPvF-5O5wnrUTA__AnfJXGnuXGwx-mIbGwOH-ygjw4utmxu4K8gU30_mDhCeDuJWr6XNFQz0JBqL7pL5lWkry06k8-MBb0YKDri0Z2822l8B9tj-6qL0BYdpMkhe8nvNcSAHzBaiY7fSpAuirgMWP4nYpsPdQbAveuY6CX8viIAzgcN8mAhE3JpopSF8_F2xySWvcXuejem5a0dJPaYn_WsEPBgT20acdBsbW0jjzDFgBYi4_6JKGeAYGppROgtFITHY6YgbRtT1xb1f5Y_ROVlCzuKMQCv5lq_-f10MAoWUUR8WkyrcM5hQEEKzRx2g9-OkV8ugdfBws6soS2S-e2_6THGDcKKPXrg2KbNSRBSn-ybJRwKgkcEHuEDImLFYQTroh-IHdAZHRUuAVoC4KvzkoxenyOs1HJuKrFf6sTJbvcw9URmS-6Z9liB7nuJVh3XI3PJ2CELGATgGxA3Y_t67nWhTKhDYf4Uto_e0sKr0lBv4IalObinGwEY0ieL5UYEZ6iDV_7ZBlaiHZJAPuPF54e5mpGO3YfOWqsoBiet1A4urTWKu-SUHpIfx8eweyxM5dehIUF3GJdjI08itKDQtZXi83wC9A4oVn-CBJgO04lpxZGXzZtLwqtgSaf5WTKvE1WdSFSwtofKqASFOkaNNovSk7HTWQMm8EBHE__4GjGO0ior4eeIGFb9oYexn7H60kniWpwssZzfUvM-f2oDI-aPIjkZwHWBzVAW8QJCqiJ9a61LGB5FKgxIA-x8YUeW0OW0gAHsWhtkxDbZjvd5CC4fl1HHAu2YH5zFx8pzj08rk3lC9UrfF4snNxsNc1eQRHo3XcqN7pZ3RFBsUgH4koiog7vlUoNKgtm51ySQKbLqXIMYYszVKAoRsVjRFr15AaA2ZMWWtRls2tsgQ3O1i5I5sgNN6_kBAlwgmVAs26NHbklopVv30ebDYtUmC-DR3PVtl5Ik4PsgjWpdKd6F-9LFf_tQDun5U4phhgT_JsK1hQA3Reu0irgd83-BVqGIhawFsh3tRbwBItCFUAk8nH-an5nSUM9K-fL087M0o2NQDaGSiaeE9YjwxOPJxcpVHGYR0xf4yVpi01hp7KvT2hZ_xZWVlJy5ZfTXzr2-32VbZQil2LpcpKE2SPGFqPM3DqUbXsJRKmxC-Tzkyax4ijIKe0Rk6KLIJ3oiG7s59KF-762vI2wat68-7deeqXN3WLJg0VJwIM0BJbMBtcBFlEx3b8fxZK_Mh_El6Zsd0vyyU7aXNFvkdDG80NnpUEdV49okFTQhMd_Mf4BhsHjN-T57kxcYw8zH-qfFYyB2lFSgZQ8sDvOH8-mApjHCNDCqybUZYiTaMdmpV6WR8E6N3BIAhkl3STLFUNXAojkPs98EfSzS-hg__O-YgwkIm8LzdMqPVdTp38YZ0ZhX2dQlR9djd67a0dw3fC830ETUC58c6wxz9iH_OSy1DJSb6DCi8k8SD_djtHAIb1DYeusljv0okoL3hLs74Xjv3wes3TkXq9QxikDZsuMdSqUvfg6nizhtqsHaPlntkknTittZc-i-YSWV1tFAPFmP_8KP_SyS5oL-cUY8JYv-JXXKbmjiMN0KieEjCJ5LNidG2gBGs5EZH80ZtVc2QhQm590DkdHDMSqhvzj7QjyHBEYK4bdBDheHVcex8odQ7K1OVvUA4VAPQYaY6ZMtI31bL1y1RXJ1pI7Q7yfrE_Z6F66uxcgPVmW0n97YfskoITSapfYpFDMAW-DOqQg3zIIrxhn43CBm5roy5qJ_pxpWtNPls9w9myLq5TDRbgVlJFyBbXcpkpCJWFz43uxZ9YO_KQe5OSsU72kzvdaK1SaUq5GqOLksagxCrCOf4vml9To2BECBo8j3o5cYHQ5NxPPehcmdpj_7720GKgth3tLTNoaEtWPXvXOtg4OqmvWJrVCMO57h1AAJIgKdlezrbmKRM9ZLqJtRfIdlWiHnfcjdAqauWcJrL33IXWu8wzaX9EqOeHPIbB0isp0RfqFYAjZ14Dce9fYUR9YRIvBEpXDZePIy4QX3CYDsvqpYYGvdMrXY4T7WI8usXlQ2snicdCxPZSOLYFjpIiPK0r-0j2zYnVuSwJNRE7tfuiaeaGtWVrM6IH7b3WxNMsg.y2jKuIAIL4f_ZVz_vXopzA-_vcI-gOlBLTjHtH16LRM\",\"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\":1776120736384},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyMjIzNiwiaWF0IjoxNzc2MTE4OTM2LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiJjNDkwOTBkNC0zZDU4LTRkM2YtYTgyOS1hMzQxNWIxZTUxZjYiLCJhdF9oYXNoIjoiTEtlRm1xWjF1QzY3VmpLYWtqNEpkdyJ9.j6qSw3k7CQ_gNphpdpBR8jRVo93NKMc1f9RM_xNgK7Q7a0CHEkTG9KU6yjwwd2ax4QCqt7ZUnntiVtY7vzYsL7m_iMNRw5KgWZsAxhayF63Wcf1SL-n_SFCkuwer2cn2IIKEUbZU6gjPOJXQFCsGSk4zKV1vBPfK58Xehwd0vqatbWeLAPf-wL5FdxmbBgXgsEwKr2VT5SvOJAhudwMT4OEcJU6jT9p0m_qQ_c0LeTk0G3DSY8rV6oyDkWl6aLLmsQ1emt9XFOqK5KCzQ3BLf-KeEAYE_3ChC9oG8ffeexdL1la_JnnnwPThP4OdpFM4VKocF3vgZE-dWDxttfm03Q\"},\"dpopKeyThumbprint\":\"tWbRqd-LVL_MhtGKggl8lgZo8HvAF3PcH-5vmA-xXHQ\",\"issuedAtEpochMs\":1776118936384,\"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\":1776118935000,\"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}" + }, + { + "name": "stellaops.theme", + "value": "system" + }, + { + "name": "stellaops.auth.session.info", + "value": "{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"expiresAtEpochMs\":1776120736384,\"issuedAtEpochMs\":1776118936384,\"dpopKeyThumbprint\":\"tWbRqd-LVL_MhtGKggl8lgZo8HvAF3PcH-5vmA-xXHQ\",\"tenantId\":\"demo-prod\"}" + }, + { + "name": "stellaops.sidebar.preferences", + "value": "{\"sidebarCollapsed\":false,\"collapsedGroups\":[\"evidence\",\"setup-admin\"],\"collapsedSections\":[]}" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-full-bootstrap.auth.json b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-full-bootstrap.auth.json new file mode 100644 index 000000000..152db604f --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-full-bootstrap.auth.json @@ -0,0 +1,55 @@ +{ + "authenticatedAtUtc": "2026-04-14T04:53:27.489Z", + "baseUrl": "https://stella-ops.local", + "finalUrl": "https://stella-ops.local/", + "title": "Dashboard - StellaOps", + "cookies": [], + "storage": { + "localStorageEntries": [ + [ + "stellaops.auth.session.full", + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjE0NDIwNCwiaWF0IjoxNzc2MTQyNDA0LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiMjEzMTc3YmEtYzA0ZC00ZmU2LTg4NGUtNTc3YzBiYTIyNzAzIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxNDI0MDMsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.onH9C2hQSynMFyMgelYPg181tl9KDdqHToghpKMrcBvI5QwQ8Yy5PDHcKhVFcRLjvIfVoQHuCjWcLbTF6ZR7l5HNJ2a8qUOf_YMqgWGE32VlY8IAb45a4OwlWzZ1wcNczGguqtcvLvVE6C4TjpIG_4UCB57ewKq2c3U7OT1Yz9Z9Bs5dlyGUogMyFHxMsbHzg0dC9F2Xc_EAdNfg5UAdw-TmMKj__FLZ9YlGxdJfTnah_JoJhwz7oZ0DwyMIUv2NiO_GTaiVHRHcBqualYpu34JggZo_I3TOyf_QzkyAAkmUNrdmfAneXhUUpU-NubXetpqQalWlOuzIk6Nug04_yw\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.ul6tJyv42BUvAXWu8HjImZ8gA0siE0UXjfKq6OqM6GG0AFp4pOm1tfIOHyxdxmkrlrCpS49tW-xwQBPTLUVQXSZwXdG2jUaN1lpaCPTfHm1pPQY5eiDJMrVXfGZbNPem0LWlJFzQzp0543P9GUi10Uqjz9v51vYnf1QBVDpe4sWAGa7GsVVjLIYB6n0-XMIkDV1baJO9GsN01t0_jWM3A6pHb3BnDTR8mCAcq-eE0a9YWd-N6x2eLeeqVxxZDy3JaatpEUR4mOSfsZVRU1SY-TVT3r275FMPOOPBxt-0yfYJWRsNHNL2fIkf4MGzypGyW5fdUlxqn_e0XqzRRHwvcQ.zYumAiU1ov-kFbhSAdgBTg.3xjI3jmXYBCIRqcpcSHIFw40ELrLxePsLBV8gHO9Bm-Ty9dDhRSg3XVS2jR-J5YFQJPGlub0ybTQI1OK8i8JbnApxUhyT_GL8AuBzP3JsleiJYSMGy0VpC_DqTTW2wIpfadU1pQ74acxBvUR7tjploPHHrSSBkFbT8vAzAOaKJF5yNF-zbUIy-_aci2EmhfGmN_TzgQ2QMv22KkAUMkrl64wydtAJ7iSl2Hp_W1FcD34D5dLzqEEYN_zocVs6oZgQbtyIeA1_Pt8-HSGBmEMBNCNNTK5RClCPgjbQlFWrFiw2DqlEjAu2KqT92yvgdPFRcgkr5QPWS56lcIuiNFc9-kyef2ZWEE8_anhn0EpM15G_TVFl55z0iprZ8OJh1P6W37oUpyw4eUaOM6xJw2t-QjiFsyLmFvVZDJY0zyWk6aFAXKKeD7RytUC1QNeqNkXuIBQCZ3t4xTS1OYHXtYtcdovLnplpcplt3H3WEi91R33zr8o6U5mlMwSCU5PxGfkcn4EF_XYEdor_NA-RAMrju2k09PgW2fxn3KlmcuXSslmChjAo3zJZ5LLou3UIRDU1nALcq0XffSso9cWr-zxn5ZAOuuuDs0R6llCnLTEvX1gyqZglnsCNOsQ6J8fDwVSdN0u72rLtFf7Q3NDCoLj5Bdc5oPwEpf4bbDbaCtSKfiXQGggigLBaoqG9G3JsEUQL4WYBWUILDFnFOukEiC6rk6Rfa_o-6ijgWdv0mldwXWrivDJIQINWdpHVBaAVPR5d-eJJs5SJx3k8WAiQaU9sqStSkjKlo6VY8Ti36ARUuSBJibgUtawemiO8CpVumiXt4zjLPEHdgWBg-x8-gxwEIK9FPgj7HMmPGJlGA3xZ6ueWkCQ81AwFY6HCJNAyfp7eaeBLt-ua1hDCzWYOwO2rZKUiVcbFYdR5kbHwObsT1AqEZc6GW8dEU_i_-0OdAYTnxOBDBCTnuOjCnIMsqgXf0c5ypMDXe7hG42FFE83uyg4CAU4PZeuu0niqxiX3NYfdAtr6zzELAK06y9scecngHF3HijKVjuRr1FR4o88j8zCUIbyAbhGSsP_G3CasQNgRmPfOeX165YvJf2JXyf9IN9ZtCMs8VplsUEF6rUEi1Pynjzt_OLv2DeBDON0ar5OIt8RcDklYZDkemMv6vWOA0arINPWIhdzPag1JMeEYlNfM9sWDRYvCGBUlnFCeDgOQRpBpRDayZOid2rzgQko3v4Exnznu0INk5oOs0p7a9p7sZDKuRPsv6KUvpZza_JvE7nJcxPf1QXGRi90rca1G1ced67sEwygzRjq9g_fCmUJIzzPKpndEl0n2Dr6A74j1wL7bH1VtrHSQNwgOSusRSd6qdQ1Xztun1fXvunGDGMqlBAayIPhmcKHJgcabgEZ_KvY2XU9QKt4g2Vnoj9wXOmxJRdrqdpv8TIpZSibu7w_Sg-RFxKhc616I4MqAyOxfXkU76VPF5pTa8Ijl0nuuzB2_7mO1bAkoMdKjq5lDSHPluK5HpvCfK6kAClNWQ2tuIs-UEoUGFSQE8Itxt7HTKkZVtQRH2fflkL96p3URob1kqLTKDHnBqMphgxqKYmyQySzcTca_WzJKrib2Ms0v9wchMR8rJADkgvcOQi9Pqk3iVTA817cPPU8mtvm42tSj1qQGUjy0L4IXvZrLc4cDRT2L1SMtm70tIbOjbIDYN5UrLbha7yPBHlC7nDj21c2YkkQ_aXwKHGPz0n07UgSCiW5Yx1m7noRftMg5sw5wGh60suOtXfWOap_kmydBkzr6cciJnIYC26cBV1LOo0T-c0SNfG8uK-uLHtpfVZNphPGAn6durXFY0NJP50kJRl_SbRR2OhM-Vhk5YuwEk9LMMu8IVCWAfLJBWrtPGiq1SKK0RvFwZro9eXsD5GY3RIrSVWlUO2zWo5mfXpd-Me3e8adNzTLPzEVtYSvbLrj-AgErBq8wfQ_RQKGv_9a6EjwwobRK6JtJUYcAI6LltFeq_uHpEO1EDXgbLhpuxreJtzg33nhH4rTMxOtb5M5mjypdbWRGB6zGd5A68VMU-KPAfEbg0xT1C6570RnvgwB8A071AWSF7Xfu0P2VBjI04Pwna-rpqfhvH3oGj9ImWzLrEkBknE1SB1p9yaQJ4Rjt7r7WIsOFGDv35BR0pl_jZ5iB7_ZfsXlN218mWOSYWGwdfcQhlJ8vsKxHwjRjt_8Og4v-LOxh7Kan-BmbG-95HLWEu-RBxOh7mx5kgzMmvKHLYhte4Ab6uqzOge_ss7IYuOxRIPDJdwkzGVdJyn2821zYwNBLh1oCBRsUa8dqiMWCPZQHmgjfnTFJZ5-3w-42Ma9_TdW6M9vhstUKz9y-mPKDX4GA3FbdxXkhUY3SiMV-uOeOpMX6S83xB_KPv5aAAvj-FuK3FHA540f9XKbmoQRX5CA6zb_a0jAQptZ-HSIUrOw7SwRar5sfkJZvZ_R6G9tf2HzDl-arZaRwpQ7YkVfKUAaNtvRxueLms3RmOJTjlliwn3XKLQxcCtMU0TNievMnd5ChFYmkhralVp2YmlOmUqEaCmDSqEQ4SmfdtImsm1pSiLDYesT6dH2dQhP4NQYOsoIRE5K4UR4eJcqtgGkzBC9RvZuidYCLxbnzzOwfs946v4MW3n2yk-IlbkZpaBFZ8iMRLB3OTSxg9t0VY46zi-7v6hsn7Psa2iPxmLEv-0Ng0u2HoC4AIxDcWJw6ZTEzIdfJ2GFIV3Ec3zn3mUc64xQvDfLMgONVH3a79GlCwMiexwTVYYURm9EFQSYZT4RME8n_7x6SQwQkKdV6xpRecjxhX7Fk3vBZCLZUJii1ZV8q6LCGhlTVA18Q6-wmF-5qk9rnd3j4PzRB_gz3PyBDBC8AUflb-EB9KN20ljAn4Hvl3v1kBxbXymaAmwRP2fkmQQPtlzp_U3a5xOv0UkjSqoavHTJ7VUwI86BTCA8fUS4pwmB9jg-9ac91o2mDmKzCkyv924iCN9EA2QavwO8fPBsWUDWKElaPoDi0cry4yBcJqrBOO4y_t29pDdObtg24NpJd-YKgdcDnLAjvdAz6lf6IMapaQ2eQYHOVQ9meJeQcKlGA4j98D5eHBb13kC-g-qSpYrvouFikdKQ_nwmferA6K2bIFOxhsbF-F7f96ggbz0mfg0QZYvxuAnevehrORPfbwVNjp8QPGOyC82VmuPbN6AMNQmWSpHWzMRlfGFt5UAH2RVoXc-0QWpfLx6snrXk6kN3oFFIwm_T_lt2UdfmcIS_KUkvssZu_qI2qoMdi5jB8f232OIPw4O2wJsJQwKzZsZDVXv67LopOc7WBantFmQDPLlLxxARA5grTY-czfUS9VwFdaMvjJyhqNaIuz4dbJa0wL8M_DebOJ2zfq0b7aOxWU4qtjabiHJsoLfZGmja30reZNtrVZueJX9AfbAgWlDrcktfQHjg5PXzszXP9dR0e5kvI42C8STXMIKzPthvR2iH-bmXVvD8lL7voFBoBXZ0EZ_6bMkGqfJpojMsZCa8EvhLcE6FGRaE24Ff993WqCpaa2Cu8DfKlcOKtYOlTFJKGPAba_uM3hVrpqj9SaWXWW6kJmEJKUwn1-r20COw1sqlstVUYz43p7BU_Gfdwah-0u3AKwNzQz4A6B9tKA4uJ5E2m_Y6apLWf8vHn8Sl3XJ-FHeR422vtZn-Cu9yWO3pThZGhQ2g07e5MHovUAMHmJvboStKeqWAP7Jn4BcjEfH1hv1roer2pwpaRHml-TWglAPfb_6pDTmK3ZF0GJNjiwtXdLlE5RY4yCqJsQJpLv2HWsTJZXXMMNqun76ONb4p_H_zphy7zA7muubzftZuTI7Abx0Z9fITGxwkACAudA_R5bxvBkq40s_8ORr7yUs0pQ9euYntUPRYpcYmMA4N1W8RIMCvcv_P0HP9l2imvTywVSugJ_aw0nJVNHVyLsWHJkL0_YMnHsC9KqdvVs8QEh5Wgeq4mSFrDEUtXPMKtw3K45g7YqkV3V3ASn3a3lQe-2sRgVu5q3wHkvc5CEovjJRo-dwqKcjVvwBkNLaWSYnWuyteamkxeeh4tFwiNFcnyxj_lZt30mQJVQkMeAWSa5pLT1xBRiRPfJ5IXQv9HcWMs3VtozwrsAvKCBmLxD7yzfuIpWL4NeESAp8aHBJeei_dB-j22qvm1auRlS2WC8Rxw545yIyy1-a1A2ZzAPQZ3cWfvBo6aFeaiW2ffJ3JDAsUGJ7TgWR_UGVdcZtEslX-vfzV3pYNIy__xEvAwmLGDspiHfLitNjOT3wuCI668HNA7dqNk-uCWNk7rOxVRMcvZ8RU9NVBuXksBlgkYoyBx5V6JbSRClBjtXFA0OFNlHh6H965sekFWMq1_shp_YX66ZO_yt_jOxDEECwowIFOmpbcpZzI4FKb8jNjKSUCLPU0rkNnCxN2Qy-9HVhCymirjw_zUQG1ifbIqUHhmHTgy-YuteqmBVkvxo6dXp4-EOK4Mx8A0rErE8TnG0QA4sLgJhrEC9bf5FcsF3A37Q_398i2N9_jkJOnXrQx8K9tCg-Hx635Vr_rrIzzboirlY9oFnMMjyuRXiSWIcZB7RR3DSqVo1QNaNyFAOeQ0CHvq9_rpyfUmPPUevuLbHE9w7YCS3hkhhT-vXBNlwJsv5vfk-67BYeV98ybDnQfSz-IiY8o54UzrYGZW1_GDjt3if5EAAWNW7vCfyMU6y7cSg15vBLhLWvqlpkCzH83LxzwGhdB6BI6_fwpXA.BNnmn3E1a-gv5fU1vqQEW5WFZlLp43sWUPaoPvCuQQA\",\"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\":1776144204750},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjE0NTcwNCwiaWF0IjoxNzc2MTQyNDA0LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiI1M2Q3NDNjNS0xMDQzLTQ3YWItYTM4Yy1iYWExOGEzMWVhOTEiLCJhdF9oYXNoIjoialZsNTYyaGFQMmZmX2ltYXNDVDRSUSJ9.e5Ht-1M9cZdCRKiluQfoQFDk4xez7CrNP-ef2fDmFNzCSpce8q8hS0X-H7M0GRksQwtizCL2BSRe55J3wedU5o_ZBhzxb64hGCxbh4UOr1opXXXQSezK7QJpd-VoiVXjsC959xU7gk04eO3wkPuTK7DnIv_p7ZUGXvHfcwVx15yKPBWodl4eCdDL3te7gbmglCiAcThis3i4f4t551udMHNl8-SZxWeG4rQ3ACXhgnR_05IMrewOIJkyvNKfsCgYt2hJbLMpAO4VNxA2-8R4eukJCW-q_0-V98PAaNNUHNNHS8HyZawJ9KO2eDAz712MnkZo5Uf0mbc1FxUdLDB5Hg\"},\"dpopKeyThumbprint\":\"B2Ki6kkou-bE6e9JInOj1Zopx2-DjG_bPuHvdh7kRLc\",\"issuedAtEpochMs\":1776142404751,\"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\":1776142403000,\"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}" + ], + [ + "stellaops.theme", + "system" + ], + [ + "stellaops.auth.session.info", + "{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"expiresAtEpochMs\":1776144204750,\"issuedAtEpochMs\":1776142404751,\"dpopKeyThumbprint\":\"B2Ki6kkou-bE6e9JInOj1Zopx2-DjG_bPuHvdh7kRLc\",\"tenantId\":\"demo-prod\"}" + ], + [ + "stellaops.sidebar.preferences", + "{\"sidebarCollapsed\":false,\"collapsedGroups\":[\"evidence\",\"setup-admin\"],\"collapsedSections\":[]}" + ] + ], + "sessionStorageEntries": [ + [ + "stellaops.auth.session.full", + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjE0NDIwNCwiaWF0IjoxNzc2MTQyNDA0LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiMjEzMTc3YmEtYzA0ZC00ZmU2LTg4NGUtNTc3YzBiYTIyNzAzIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxNDI0MDMsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.onH9C2hQSynMFyMgelYPg181tl9KDdqHToghpKMrcBvI5QwQ8Yy5PDHcKhVFcRLjvIfVoQHuCjWcLbTF6ZR7l5HNJ2a8qUOf_YMqgWGE32VlY8IAb45a4OwlWzZ1wcNczGguqtcvLvVE6C4TjpIG_4UCB57ewKq2c3U7OT1Yz9Z9Bs5dlyGUogMyFHxMsbHzg0dC9F2Xc_EAdNfg5UAdw-TmMKj__FLZ9YlGxdJfTnah_JoJhwz7oZ0DwyMIUv2NiO_GTaiVHRHcBqualYpu34JggZo_I3TOyf_QzkyAAkmUNrdmfAneXhUUpU-NubXetpqQalWlOuzIk6Nug04_yw\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.ul6tJyv42BUvAXWu8HjImZ8gA0siE0UXjfKq6OqM6GG0AFp4pOm1tfIOHyxdxmkrlrCpS49tW-xwQBPTLUVQXSZwXdG2jUaN1lpaCPTfHm1pPQY5eiDJMrVXfGZbNPem0LWlJFzQzp0543P9GUi10Uqjz9v51vYnf1QBVDpe4sWAGa7GsVVjLIYB6n0-XMIkDV1baJO9GsN01t0_jWM3A6pHb3BnDTR8mCAcq-eE0a9YWd-N6x2eLeeqVxxZDy3JaatpEUR4mOSfsZVRU1SY-TVT3r275FMPOOPBxt-0yfYJWRsNHNL2fIkf4MGzypGyW5fdUlxqn_e0XqzRRHwvcQ.zYumAiU1ov-kFbhSAdgBTg.3xjI3jmXYBCIRqcpcSHIFw40ELrLxePsLBV8gHO9Bm-Ty9dDhRSg3XVS2jR-J5YFQJPGlub0ybTQI1OK8i8JbnApxUhyT_GL8AuBzP3JsleiJYSMGy0VpC_DqTTW2wIpfadU1pQ74acxBvUR7tjploPHHrSSBkFbT8vAzAOaKJF5yNF-zbUIy-_aci2EmhfGmN_TzgQ2QMv22KkAUMkrl64wydtAJ7iSl2Hp_W1FcD34D5dLzqEEYN_zocVs6oZgQbtyIeA1_Pt8-HSGBmEMBNCNNTK5RClCPgjbQlFWrFiw2DqlEjAu2KqT92yvgdPFRcgkr5QPWS56lcIuiNFc9-kyef2ZWEE8_anhn0EpM15G_TVFl55z0iprZ8OJh1P6W37oUpyw4eUaOM6xJw2t-QjiFsyLmFvVZDJY0zyWk6aFAXKKeD7RytUC1QNeqNkXuIBQCZ3t4xTS1OYHXtYtcdovLnplpcplt3H3WEi91R33zr8o6U5mlMwSCU5PxGfkcn4EF_XYEdor_NA-RAMrju2k09PgW2fxn3KlmcuXSslmChjAo3zJZ5LLou3UIRDU1nALcq0XffSso9cWr-zxn5ZAOuuuDs0R6llCnLTEvX1gyqZglnsCNOsQ6J8fDwVSdN0u72rLtFf7Q3NDCoLj5Bdc5oPwEpf4bbDbaCtSKfiXQGggigLBaoqG9G3JsEUQL4WYBWUILDFnFOukEiC6rk6Rfa_o-6ijgWdv0mldwXWrivDJIQINWdpHVBaAVPR5d-eJJs5SJx3k8WAiQaU9sqStSkjKlo6VY8Ti36ARUuSBJibgUtawemiO8CpVumiXt4zjLPEHdgWBg-x8-gxwEIK9FPgj7HMmPGJlGA3xZ6ueWkCQ81AwFY6HCJNAyfp7eaeBLt-ua1hDCzWYOwO2rZKUiVcbFYdR5kbHwObsT1AqEZc6GW8dEU_i_-0OdAYTnxOBDBCTnuOjCnIMsqgXf0c5ypMDXe7hG42FFE83uyg4CAU4PZeuu0niqxiX3NYfdAtr6zzELAK06y9scecngHF3HijKVjuRr1FR4o88j8zCUIbyAbhGSsP_G3CasQNgRmPfOeX165YvJf2JXyf9IN9ZtCMs8VplsUEF6rUEi1Pynjzt_OLv2DeBDON0ar5OIt8RcDklYZDkemMv6vWOA0arINPWIhdzPag1JMeEYlNfM9sWDRYvCGBUlnFCeDgOQRpBpRDayZOid2rzgQko3v4Exnznu0INk5oOs0p7a9p7sZDKuRPsv6KUvpZza_JvE7nJcxPf1QXGRi90rca1G1ced67sEwygzRjq9g_fCmUJIzzPKpndEl0n2Dr6A74j1wL7bH1VtrHSQNwgOSusRSd6qdQ1Xztun1fXvunGDGMqlBAayIPhmcKHJgcabgEZ_KvY2XU9QKt4g2Vnoj9wXOmxJRdrqdpv8TIpZSibu7w_Sg-RFxKhc616I4MqAyOxfXkU76VPF5pTa8Ijl0nuuzB2_7mO1bAkoMdKjq5lDSHPluK5HpvCfK6kAClNWQ2tuIs-UEoUGFSQE8Itxt7HTKkZVtQRH2fflkL96p3URob1kqLTKDHnBqMphgxqKYmyQySzcTca_WzJKrib2Ms0v9wchMR8rJADkgvcOQi9Pqk3iVTA817cPPU8mtvm42tSj1qQGUjy0L4IXvZrLc4cDRT2L1SMtm70tIbOjbIDYN5UrLbha7yPBHlC7nDj21c2YkkQ_aXwKHGPz0n07UgSCiW5Yx1m7noRftMg5sw5wGh60suOtXfWOap_kmydBkzr6cciJnIYC26cBV1LOo0T-c0SNfG8uK-uLHtpfVZNphPGAn6durXFY0NJP50kJRl_SbRR2OhM-Vhk5YuwEk9LMMu8IVCWAfLJBWrtPGiq1SKK0RvFwZro9eXsD5GY3RIrSVWlUO2zWo5mfXpd-Me3e8adNzTLPzEVtYSvbLrj-AgErBq8wfQ_RQKGv_9a6EjwwobRK6JtJUYcAI6LltFeq_uHpEO1EDXgbLhpuxreJtzg33nhH4rTMxOtb5M5mjypdbWRGB6zGd5A68VMU-KPAfEbg0xT1C6570RnvgwB8A071AWSF7Xfu0P2VBjI04Pwna-rpqfhvH3oGj9ImWzLrEkBknE1SB1p9yaQJ4Rjt7r7WIsOFGDv35BR0pl_jZ5iB7_ZfsXlN218mWOSYWGwdfcQhlJ8vsKxHwjRjt_8Og4v-LOxh7Kan-BmbG-95HLWEu-RBxOh7mx5kgzMmvKHLYhte4Ab6uqzOge_ss7IYuOxRIPDJdwkzGVdJyn2821zYwNBLh1oCBRsUa8dqiMWCPZQHmgjfnTFJZ5-3w-42Ma9_TdW6M9vhstUKz9y-mPKDX4GA3FbdxXkhUY3SiMV-uOeOpMX6S83xB_KPv5aAAvj-FuK3FHA540f9XKbmoQRX5CA6zb_a0jAQptZ-HSIUrOw7SwRar5sfkJZvZ_R6G9tf2HzDl-arZaRwpQ7YkVfKUAaNtvRxueLms3RmOJTjlliwn3XKLQxcCtMU0TNievMnd5ChFYmkhralVp2YmlOmUqEaCmDSqEQ4SmfdtImsm1pSiLDYesT6dH2dQhP4NQYOsoIRE5K4UR4eJcqtgGkzBC9RvZuidYCLxbnzzOwfs946v4MW3n2yk-IlbkZpaBFZ8iMRLB3OTSxg9t0VY46zi-7v6hsn7Psa2iPxmLEv-0Ng0u2HoC4AIxDcWJw6ZTEzIdfJ2GFIV3Ec3zn3mUc64xQvDfLMgONVH3a79GlCwMiexwTVYYURm9EFQSYZT4RME8n_7x6SQwQkKdV6xpRecjxhX7Fk3vBZCLZUJii1ZV8q6LCGhlTVA18Q6-wmF-5qk9rnd3j4PzRB_gz3PyBDBC8AUflb-EB9KN20ljAn4Hvl3v1kBxbXymaAmwRP2fkmQQPtlzp_U3a5xOv0UkjSqoavHTJ7VUwI86BTCA8fUS4pwmB9jg-9ac91o2mDmKzCkyv924iCN9EA2QavwO8fPBsWUDWKElaPoDi0cry4yBcJqrBOO4y_t29pDdObtg24NpJd-YKgdcDnLAjvdAz6lf6IMapaQ2eQYHOVQ9meJeQcKlGA4j98D5eHBb13kC-g-qSpYrvouFikdKQ_nwmferA6K2bIFOxhsbF-F7f96ggbz0mfg0QZYvxuAnevehrORPfbwVNjp8QPGOyC82VmuPbN6AMNQmWSpHWzMRlfGFt5UAH2RVoXc-0QWpfLx6snrXk6kN3oFFIwm_T_lt2UdfmcIS_KUkvssZu_qI2qoMdi5jB8f232OIPw4O2wJsJQwKzZsZDVXv67LopOc7WBantFmQDPLlLxxARA5grTY-czfUS9VwFdaMvjJyhqNaIuz4dbJa0wL8M_DebOJ2zfq0b7aOxWU4qtjabiHJsoLfZGmja30reZNtrVZueJX9AfbAgWlDrcktfQHjg5PXzszXP9dR0e5kvI42C8STXMIKzPthvR2iH-bmXVvD8lL7voFBoBXZ0EZ_6bMkGqfJpojMsZCa8EvhLcE6FGRaE24Ff993WqCpaa2Cu8DfKlcOKtYOlTFJKGPAba_uM3hVrpqj9SaWXWW6kJmEJKUwn1-r20COw1sqlstVUYz43p7BU_Gfdwah-0u3AKwNzQz4A6B9tKA4uJ5E2m_Y6apLWf8vHn8Sl3XJ-FHeR422vtZn-Cu9yWO3pThZGhQ2g07e5MHovUAMHmJvboStKeqWAP7Jn4BcjEfH1hv1roer2pwpaRHml-TWglAPfb_6pDTmK3ZF0GJNjiwtXdLlE5RY4yCqJsQJpLv2HWsTJZXXMMNqun76ONb4p_H_zphy7zA7muubzftZuTI7Abx0Z9fITGxwkACAudA_R5bxvBkq40s_8ORr7yUs0pQ9euYntUPRYpcYmMA4N1W8RIMCvcv_P0HP9l2imvTywVSugJ_aw0nJVNHVyLsWHJkL0_YMnHsC9KqdvVs8QEh5Wgeq4mSFrDEUtXPMKtw3K45g7YqkV3V3ASn3a3lQe-2sRgVu5q3wHkvc5CEovjJRo-dwqKcjVvwBkNLaWSYnWuyteamkxeeh4tFwiNFcnyxj_lZt30mQJVQkMeAWSa5pLT1xBRiRPfJ5IXQv9HcWMs3VtozwrsAvKCBmLxD7yzfuIpWL4NeESAp8aHBJeei_dB-j22qvm1auRlS2WC8Rxw545yIyy1-a1A2ZzAPQZ3cWfvBo6aFeaiW2ffJ3JDAsUGJ7TgWR_UGVdcZtEslX-vfzV3pYNIy__xEvAwmLGDspiHfLitNjOT3wuCI668HNA7dqNk-uCWNk7rOxVRMcvZ8RU9NVBuXksBlgkYoyBx5V6JbSRClBjtXFA0OFNlHh6H965sekFWMq1_shp_YX66ZO_yt_jOxDEECwowIFOmpbcpZzI4FKb8jNjKSUCLPU0rkNnCxN2Qy-9HVhCymirjw_zUQG1ifbIqUHhmHTgy-YuteqmBVkvxo6dXp4-EOK4Mx8A0rErE8TnG0QA4sLgJhrEC9bf5FcsF3A37Q_398i2N9_jkJOnXrQx8K9tCg-Hx635Vr_rrIzzboirlY9oFnMMjyuRXiSWIcZB7RR3DSqVo1QNaNyFAOeQ0CHvq9_rpyfUmPPUevuLbHE9w7YCS3hkhhT-vXBNlwJsv5vfk-67BYeV98ybDnQfSz-IiY8o54UzrYGZW1_GDjt3if5EAAWNW7vCfyMU6y7cSg15vBLhLWvqlpkCzH83LxzwGhdB6BI6_fwpXA.BNnmn3E1a-gv5fU1vqQEW5WFZlLp43sWUPaoPvCuQQA\",\"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\":1776144204750},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjE0NTcwNCwiaWF0IjoxNzc2MTQyNDA0LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiI1M2Q3NDNjNS0xMDQzLTQ3YWItYTM4Yy1iYWExOGEzMWVhOTEiLCJhdF9oYXNoIjoialZsNTYyaGFQMmZmX2ltYXNDVDRSUSJ9.e5Ht-1M9cZdCRKiluQfoQFDk4xez7CrNP-ef2fDmFNzCSpce8q8hS0X-H7M0GRksQwtizCL2BSRe55J3wedU5o_ZBhzxb64hGCxbh4UOr1opXXXQSezK7QJpd-VoiVXjsC959xU7gk04eO3wkPuTK7DnIv_p7ZUGXvHfcwVx15yKPBWodl4eCdDL3te7gbmglCiAcThis3i4f4t551udMHNl8-SZxWeG4rQ3ACXhgnR_05IMrewOIJkyvNKfsCgYt2hJbLMpAO4VNxA2-8R4eukJCW-q_0-V98PAaNNUHNNHS8HyZawJ9KO2eDAz712MnkZo5Uf0mbc1FxUdLDB5Hg\"},\"dpopKeyThumbprint\":\"B2Ki6kkou-bE6e9JInOj1Zopx2-DjG_bPuHvdh7kRLc\",\"issuedAtEpochMs\":1776142404751,\"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\":1776142403000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" + ], + [ + "stellaops:wasEverAuth", + "true" + ] + ] + }, + "events": { + "consoleErrors": [], + "requestFailures": [], + "responseErrors": [] + }, + "statePath": "C:\\dev\\New folder\\git.stella-ops.org\\src\\Web\\StellaOps.Web\\output\\playwright\\live-setup-wizard-full-bootstrap.state.json" +} diff --git a/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-full-bootstrap.json b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-full-bootstrap.json new file mode 100644 index 000000000..f7082f1f4 --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-full-bootstrap.json @@ -0,0 +1,4 @@ +{ + "generatedAtUtc": "2026-04-14T04:54:01.188Z", + "fatalError": "locator.waitFor: Timeout 20000ms exceeded.\nCall log:\n\u001b[2m - waiting for getByRole('button', { name: /^Apply and Continue$/ }).first() to be visible\u001b[22m\n" +} diff --git a/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-full-bootstrap.state.json b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-full-bootstrap.state.json new file mode 100644 index 000000000..78de8c402 --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-full-bootstrap.state.json @@ -0,0 +1,38 @@ +{ + "cookies": [], + "origins": [ + { + "origin": "https://stella-ops.local", + "localStorage": [ + { + "name": "stellaops.auth.session.full", + "value": "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjE0NDIwNCwiaWF0IjoxNzc2MTQyNDA0LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiMjEzMTc3YmEtYzA0ZC00ZmU2LTg4NGUtNTc3YzBiYTIyNzAzIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxNDI0MDMsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.onH9C2hQSynMFyMgelYPg181tl9KDdqHToghpKMrcBvI5QwQ8Yy5PDHcKhVFcRLjvIfVoQHuCjWcLbTF6ZR7l5HNJ2a8qUOf_YMqgWGE32VlY8IAb45a4OwlWzZ1wcNczGguqtcvLvVE6C4TjpIG_4UCB57ewKq2c3U7OT1Yz9Z9Bs5dlyGUogMyFHxMsbHzg0dC9F2Xc_EAdNfg5UAdw-TmMKj__FLZ9YlGxdJfTnah_JoJhwz7oZ0DwyMIUv2NiO_GTaiVHRHcBqualYpu34JggZo_I3TOyf_QzkyAAkmUNrdmfAneXhUUpU-NubXetpqQalWlOuzIk6Nug04_yw\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.ul6tJyv42BUvAXWu8HjImZ8gA0siE0UXjfKq6OqM6GG0AFp4pOm1tfIOHyxdxmkrlrCpS49tW-xwQBPTLUVQXSZwXdG2jUaN1lpaCPTfHm1pPQY5eiDJMrVXfGZbNPem0LWlJFzQzp0543P9GUi10Uqjz9v51vYnf1QBVDpe4sWAGa7GsVVjLIYB6n0-XMIkDV1baJO9GsN01t0_jWM3A6pHb3BnDTR8mCAcq-eE0a9YWd-N6x2eLeeqVxxZDy3JaatpEUR4mOSfsZVRU1SY-TVT3r275FMPOOPBxt-0yfYJWRsNHNL2fIkf4MGzypGyW5fdUlxqn_e0XqzRRHwvcQ.zYumAiU1ov-kFbhSAdgBTg.3xjI3jmXYBCIRqcpcSHIFw40ELrLxePsLBV8gHO9Bm-Ty9dDhRSg3XVS2jR-J5YFQJPGlub0ybTQI1OK8i8JbnApxUhyT_GL8AuBzP3JsleiJYSMGy0VpC_DqTTW2wIpfadU1pQ74acxBvUR7tjploPHHrSSBkFbT8vAzAOaKJF5yNF-zbUIy-_aci2EmhfGmN_TzgQ2QMv22KkAUMkrl64wydtAJ7iSl2Hp_W1FcD34D5dLzqEEYN_zocVs6oZgQbtyIeA1_Pt8-HSGBmEMBNCNNTK5RClCPgjbQlFWrFiw2DqlEjAu2KqT92yvgdPFRcgkr5QPWS56lcIuiNFc9-kyef2ZWEE8_anhn0EpM15G_TVFl55z0iprZ8OJh1P6W37oUpyw4eUaOM6xJw2t-QjiFsyLmFvVZDJY0zyWk6aFAXKKeD7RytUC1QNeqNkXuIBQCZ3t4xTS1OYHXtYtcdovLnplpcplt3H3WEi91R33zr8o6U5mlMwSCU5PxGfkcn4EF_XYEdor_NA-RAMrju2k09PgW2fxn3KlmcuXSslmChjAo3zJZ5LLou3UIRDU1nALcq0XffSso9cWr-zxn5ZAOuuuDs0R6llCnLTEvX1gyqZglnsCNOsQ6J8fDwVSdN0u72rLtFf7Q3NDCoLj5Bdc5oPwEpf4bbDbaCtSKfiXQGggigLBaoqG9G3JsEUQL4WYBWUILDFnFOukEiC6rk6Rfa_o-6ijgWdv0mldwXWrivDJIQINWdpHVBaAVPR5d-eJJs5SJx3k8WAiQaU9sqStSkjKlo6VY8Ti36ARUuSBJibgUtawemiO8CpVumiXt4zjLPEHdgWBg-x8-gxwEIK9FPgj7HMmPGJlGA3xZ6ueWkCQ81AwFY6HCJNAyfp7eaeBLt-ua1hDCzWYOwO2rZKUiVcbFYdR5kbHwObsT1AqEZc6GW8dEU_i_-0OdAYTnxOBDBCTnuOjCnIMsqgXf0c5ypMDXe7hG42FFE83uyg4CAU4PZeuu0niqxiX3NYfdAtr6zzELAK06y9scecngHF3HijKVjuRr1FR4o88j8zCUIbyAbhGSsP_G3CasQNgRmPfOeX165YvJf2JXyf9IN9ZtCMs8VplsUEF6rUEi1Pynjzt_OLv2DeBDON0ar5OIt8RcDklYZDkemMv6vWOA0arINPWIhdzPag1JMeEYlNfM9sWDRYvCGBUlnFCeDgOQRpBpRDayZOid2rzgQko3v4Exnznu0INk5oOs0p7a9p7sZDKuRPsv6KUvpZza_JvE7nJcxPf1QXGRi90rca1G1ced67sEwygzRjq9g_fCmUJIzzPKpndEl0n2Dr6A74j1wL7bH1VtrHSQNwgOSusRSd6qdQ1Xztun1fXvunGDGMqlBAayIPhmcKHJgcabgEZ_KvY2XU9QKt4g2Vnoj9wXOmxJRdrqdpv8TIpZSibu7w_Sg-RFxKhc616I4MqAyOxfXkU76VPF5pTa8Ijl0nuuzB2_7mO1bAkoMdKjq5lDSHPluK5HpvCfK6kAClNWQ2tuIs-UEoUGFSQE8Itxt7HTKkZVtQRH2fflkL96p3URob1kqLTKDHnBqMphgxqKYmyQySzcTca_WzJKrib2Ms0v9wchMR8rJADkgvcOQi9Pqk3iVTA817cPPU8mtvm42tSj1qQGUjy0L4IXvZrLc4cDRT2L1SMtm70tIbOjbIDYN5UrLbha7yPBHlC7nDj21c2YkkQ_aXwKHGPz0n07UgSCiW5Yx1m7noRftMg5sw5wGh60suOtXfWOap_kmydBkzr6cciJnIYC26cBV1LOo0T-c0SNfG8uK-uLHtpfVZNphPGAn6durXFY0NJP50kJRl_SbRR2OhM-Vhk5YuwEk9LMMu8IVCWAfLJBWrtPGiq1SKK0RvFwZro9eXsD5GY3RIrSVWlUO2zWo5mfXpd-Me3e8adNzTLPzEVtYSvbLrj-AgErBq8wfQ_RQKGv_9a6EjwwobRK6JtJUYcAI6LltFeq_uHpEO1EDXgbLhpuxreJtzg33nhH4rTMxOtb5M5mjypdbWRGB6zGd5A68VMU-KPAfEbg0xT1C6570RnvgwB8A071AWSF7Xfu0P2VBjI04Pwna-rpqfhvH3oGj9ImWzLrEkBknE1SB1p9yaQJ4Rjt7r7WIsOFGDv35BR0pl_jZ5iB7_ZfsXlN218mWOSYWGwdfcQhlJ8vsKxHwjRjt_8Og4v-LOxh7Kan-BmbG-95HLWEu-RBxOh7mx5kgzMmvKHLYhte4Ab6uqzOge_ss7IYuOxRIPDJdwkzGVdJyn2821zYwNBLh1oCBRsUa8dqiMWCPZQHmgjfnTFJZ5-3w-42Ma9_TdW6M9vhstUKz9y-mPKDX4GA3FbdxXkhUY3SiMV-uOeOpMX6S83xB_KPv5aAAvj-FuK3FHA540f9XKbmoQRX5CA6zb_a0jAQptZ-HSIUrOw7SwRar5sfkJZvZ_R6G9tf2HzDl-arZaRwpQ7YkVfKUAaNtvRxueLms3RmOJTjlliwn3XKLQxcCtMU0TNievMnd5ChFYmkhralVp2YmlOmUqEaCmDSqEQ4SmfdtImsm1pSiLDYesT6dH2dQhP4NQYOsoIRE5K4UR4eJcqtgGkzBC9RvZuidYCLxbnzzOwfs946v4MW3n2yk-IlbkZpaBFZ8iMRLB3OTSxg9t0VY46zi-7v6hsn7Psa2iPxmLEv-0Ng0u2HoC4AIxDcWJw6ZTEzIdfJ2GFIV3Ec3zn3mUc64xQvDfLMgONVH3a79GlCwMiexwTVYYURm9EFQSYZT4RME8n_7x6SQwQkKdV6xpRecjxhX7Fk3vBZCLZUJii1ZV8q6LCGhlTVA18Q6-wmF-5qk9rnd3j4PzRB_gz3PyBDBC8AUflb-EB9KN20ljAn4Hvl3v1kBxbXymaAmwRP2fkmQQPtlzp_U3a5xOv0UkjSqoavHTJ7VUwI86BTCA8fUS4pwmB9jg-9ac91o2mDmKzCkyv924iCN9EA2QavwO8fPBsWUDWKElaPoDi0cry4yBcJqrBOO4y_t29pDdObtg24NpJd-YKgdcDnLAjvdAz6lf6IMapaQ2eQYHOVQ9meJeQcKlGA4j98D5eHBb13kC-g-qSpYrvouFikdKQ_nwmferA6K2bIFOxhsbF-F7f96ggbz0mfg0QZYvxuAnevehrORPfbwVNjp8QPGOyC82VmuPbN6AMNQmWSpHWzMRlfGFt5UAH2RVoXc-0QWpfLx6snrXk6kN3oFFIwm_T_lt2UdfmcIS_KUkvssZu_qI2qoMdi5jB8f232OIPw4O2wJsJQwKzZsZDVXv67LopOc7WBantFmQDPLlLxxARA5grTY-czfUS9VwFdaMvjJyhqNaIuz4dbJa0wL8M_DebOJ2zfq0b7aOxWU4qtjabiHJsoLfZGmja30reZNtrVZueJX9AfbAgWlDrcktfQHjg5PXzszXP9dR0e5kvI42C8STXMIKzPthvR2iH-bmXVvD8lL7voFBoBXZ0EZ_6bMkGqfJpojMsZCa8EvhLcE6FGRaE24Ff993WqCpaa2Cu8DfKlcOKtYOlTFJKGPAba_uM3hVrpqj9SaWXWW6kJmEJKUwn1-r20COw1sqlstVUYz43p7BU_Gfdwah-0u3AKwNzQz4A6B9tKA4uJ5E2m_Y6apLWf8vHn8Sl3XJ-FHeR422vtZn-Cu9yWO3pThZGhQ2g07e5MHovUAMHmJvboStKeqWAP7Jn4BcjEfH1hv1roer2pwpaRHml-TWglAPfb_6pDTmK3ZF0GJNjiwtXdLlE5RY4yCqJsQJpLv2HWsTJZXXMMNqun76ONb4p_H_zphy7zA7muubzftZuTI7Abx0Z9fITGxwkACAudA_R5bxvBkq40s_8ORr7yUs0pQ9euYntUPRYpcYmMA4N1W8RIMCvcv_P0HP9l2imvTywVSugJ_aw0nJVNHVyLsWHJkL0_YMnHsC9KqdvVs8QEh5Wgeq4mSFrDEUtXPMKtw3K45g7YqkV3V3ASn3a3lQe-2sRgVu5q3wHkvc5CEovjJRo-dwqKcjVvwBkNLaWSYnWuyteamkxeeh4tFwiNFcnyxj_lZt30mQJVQkMeAWSa5pLT1xBRiRPfJ5IXQv9HcWMs3VtozwrsAvKCBmLxD7yzfuIpWL4NeESAp8aHBJeei_dB-j22qvm1auRlS2WC8Rxw545yIyy1-a1A2ZzAPQZ3cWfvBo6aFeaiW2ffJ3JDAsUGJ7TgWR_UGVdcZtEslX-vfzV3pYNIy__xEvAwmLGDspiHfLitNjOT3wuCI668HNA7dqNk-uCWNk7rOxVRMcvZ8RU9NVBuXksBlgkYoyBx5V6JbSRClBjtXFA0OFNlHh6H965sekFWMq1_shp_YX66ZO_yt_jOxDEECwowIFOmpbcpZzI4FKb8jNjKSUCLPU0rkNnCxN2Qy-9HVhCymirjw_zUQG1ifbIqUHhmHTgy-YuteqmBVkvxo6dXp4-EOK4Mx8A0rErE8TnG0QA4sLgJhrEC9bf5FcsF3A37Q_398i2N9_jkJOnXrQx8K9tCg-Hx635Vr_rrIzzboirlY9oFnMMjyuRXiSWIcZB7RR3DSqVo1QNaNyFAOeQ0CHvq9_rpyfUmPPUevuLbHE9w7YCS3hkhhT-vXBNlwJsv5vfk-67BYeV98ybDnQfSz-IiY8o54UzrYGZW1_GDjt3if5EAAWNW7vCfyMU6y7cSg15vBLhLWvqlpkCzH83LxzwGhdB6BI6_fwpXA.BNnmn3E1a-gv5fU1vqQEW5WFZlLp43sWUPaoPvCuQQA\",\"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\":1776144204750},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjE0NTcwNCwiaWF0IjoxNzc2MTQyNDA0LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiI1M2Q3NDNjNS0xMDQzLTQ3YWItYTM4Yy1iYWExOGEzMWVhOTEiLCJhdF9oYXNoIjoialZsNTYyaGFQMmZmX2ltYXNDVDRSUSJ9.e5Ht-1M9cZdCRKiluQfoQFDk4xez7CrNP-ef2fDmFNzCSpce8q8hS0X-H7M0GRksQwtizCL2BSRe55J3wedU5o_ZBhzxb64hGCxbh4UOr1opXXXQSezK7QJpd-VoiVXjsC959xU7gk04eO3wkPuTK7DnIv_p7ZUGXvHfcwVx15yKPBWodl4eCdDL3te7gbmglCiAcThis3i4f4t551udMHNl8-SZxWeG4rQ3ACXhgnR_05IMrewOIJkyvNKfsCgYt2hJbLMpAO4VNxA2-8R4eukJCW-q_0-V98PAaNNUHNNHS8HyZawJ9KO2eDAz712MnkZo5Uf0mbc1FxUdLDB5Hg\"},\"dpopKeyThumbprint\":\"B2Ki6kkou-bE6e9JInOj1Zopx2-DjG_bPuHvdh7kRLc\",\"issuedAtEpochMs\":1776142404751,\"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\":1776142403000,\"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}" + }, + { + "name": "stellaops.theme", + "value": "system" + }, + { + "name": "stellaops.auth.session.info", + "value": "{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"expiresAtEpochMs\":1776144204750,\"issuedAtEpochMs\":1776142404751,\"dpopKeyThumbprint\":\"B2Ki6kkou-bE6e9JInOj1Zopx2-DjG_bPuHvdh7kRLc\",\"tenantId\":\"demo-prod\"}" + }, + { + "name": "stellaops.sidebar.preferences", + "value": "{\"sidebarCollapsed\":false,\"collapsedGroups\":[\"evidence\",\"setup-admin\"],\"collapsedSections\":[]}" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-probe.auth.json b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-probe.auth.json new file mode 100644 index 000000000..49f1099f0 --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-probe.auth.json @@ -0,0 +1,85 @@ +{ + "authenticatedAtUtc": "2026-04-13T22:13:12.041Z", + "baseUrl": "https://stella-ops.local", + "finalUrl": "https://stella-ops.local/", + "title": "Dashboard - StellaOps", + "cookies": [], + "storage": { + "localStorageEntries": [ + [ + "stellaops.auth.session.full", + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyMDE4OSwiaWF0IjoxNzc2MTE4Mzg5LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiYmViOGVlMDktN2MyNy00MDBhLTk2ZjctMWNjMTA0NTY3MzVjIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMTgzODksIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.ciSQoX-EVPzXeOivFZum8P5G0yYkfS6q-rx4-HRnYHnZUnaZ0SEPWH5vd7Qtf1kR1EXGsyl1ppzsJeHVMRVtjoFJ7mwVq4Mqk89HDsm1Jbbz8EfuXQqZ5BQxpUl0-tZH142p_HekeL52xN9vM7NT80NN-dHyQqhYvjtnSv6uHDopeeawG9KXhV3c0v8QpDHNLbisjTXDOACxqHaboM6h8Iu9c83avxOIdwym403gWz9iXFvCeh5AzivaTK3RuQXsM_9J3b-TujVlD3jMQpcC9Z2Gzf8krpLw7fSfZq84EXVNpV6Cp3M_TkxpwdSN_OLK6gl8Aej2d1Sdsn2mFGWSzw\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.Ei7-g6G7vxB34iNHdxJIg0KPsdcBY9V36ImTrCGzPTNavYtTqWLPI6gj5ZV02E080HVJBUpavMmnvVYN1OR97mR1xnU206zh62c3HC1-w2b4wJHIrYvmnays0Bq9cvrTfWJTzkBzUTEOoylf2rP_Rl0Uvqn1OzwsRIudqtryOcJRlqpNQSAzHPgKj6AynMe_KvrtWv76Lib2yTmuEdKG3rcbDma6x85nrnuk3TCCGz4RTfuh8aU0IdHOc58AyS2UiN0hIuIkNwSK4rFije_PiWb4uPuQg-58aGnkywuI78cAKTOWLKw3F5i_q_TGBtXJLYnoWfpCs6cUjtU2OMM1zg.3s9xbQLNa93wCujW_wDJqQ.9i_U_HN-KpAQWzVYY4oczfbyJ3WfRV-yIO1oGX9OW0wvsbGauH4eiw_iGGawKJb8jVHqVIRlM17lttPKJylitVeVB5fddryi5T7zkRf2uPo9RWw0tievVA-0jSLr1fOAvBS228lnJB0qjcb5n-C376_nEtx_jjcHVe35n7Mh--ZRIGIHyE3z_H6fgEcu6dvW-agaHxx4qmdWd7hostUiO1wlGaajeA4ntfAey5jHHy5ysChJdG-blICOA73ibKoDXoec4B8f0fEMLlR1iLbplcFZNG1BKDKNsKdKABPWBrh9Qve0HX5e41H1Mzby9Sk6Ph1QUMn0OiNeSKqYPMF8ovoQJq8Ouss1Dfcow_QqFj8ScmIss4aex_Uf1fkg-eIbda-woYAJcOZvKN4wTZNZZbd2gTpL_t0Ul7PYwk7B_1SZUO9Mi9H76PzI236wQYaXAN-u9QZfLSfNUfy5ive-dSoSE6vgK8ho334Bt2F7uMwS4JGNDLdeiNn8KrYvhfyK6k2xz2ZD073qkXP5h9qO3TCE5SndlleC_sRqhiYlYjbEI_EFwN4bP7OBdnwfUx9-JFwf6SeMrq2HPy0gs4081NT-YKEMWdo5LLrzQ83vR6mHadXYYHV42vTdisrVNbSko_rzVsFTINqFgq3JyEGMJo-eOTKQvuV415-CZPpewwyt-o5Q4N5Mee4zJXfrpR0ZNx4ebTph97PCZRZm2UrPkmrP8wRDIjj4dksXFSYfsjQ3DIP_-mQ7mLkg6CFXL8GTqw8E7RiOPn14L1V7CTgUcUOxZYgE9Ctxu48npb3v0W-nVcmYHkgAVOHGOdf93AbE6x3giz6ASS9MKWJ_asZ8zvA4bYV_DNMteE9MXZVXnPLyCOaGhRhQNpfMqsBK5yjEKzIAMjKdKh0KxnGQQMERohesPT-miIDZRIBiMlF7gM3vWx9XIUfoGw2KIcja9UZkN4I3qOrQS1S-2ZNptIJMphwnXqeKj_9xWBkgGXIEICo2pVA2vM3qFWdIjtbevuEhisV-cdhCtAmPh7yYoj5JTTTfKWedJQX5e0Zqfhlo8CtZcmFDTyTmb0aN_UgQ9BvxgqIfxAT6ndWZm0ofZO2rekBERRtGVxz1EUdbsv76gjEkb2ZZqOLq8K-n6E3oqwNgNuuxy9NVUkEqx8vCO5jAtJS-xZrB3d59eh1oqC0sF1GLdat6ULU_Zigh-mbnNFR-7lyjPpHGK16a_T10VBur629NLNJunfx8om6T1V_kWfPp9MJIfinSMIAFrbxSch1UcY_KjvIFJV95LFv5VpnP-wsd9LAmGo2NstouF9BSfaa-WB6KmRfA1pIO7-CIamdr2h5hO3PLML-AlXHFY1_bi-b_U9h52adzZG5meto1eky7v8bOkX1DeK9LQMy5MVYj8roiurG9SwhcZc3B3f-4UAKoh5lFDUoDK1w7bn1QPoD2aGQ0hUBB-D9Esh_m4MlDO5zO92q9Yg2WB6I_gAoojWWa0PeLJzlxJ42W4hO7mLqd1Zqoik_RHB1gO5PEhnehx5pzv4UAI-s-hOJ5LV_RrVBuX5GQFuz4OI9G9s06Tu9KyLGSu2y-woJ9C5-US25CbhTjwXtoHuYIIVR5lF8ghKCIuZZCYXuw8-K15K5gPTdkjiMcNp3yCm22jTwiM6lK3m5sj261VPtrIe7WqJkNf9YTaKCW-FTj7lDF-lVYqpkccgWxiOdyNG661JRtONpW6Tm2BVTt7DWfR31QcVGrBZA0J8xs-udj10SHi9AKHnj3tVrtUbd2n5nYqI7W9v6t6E9VBUa--fth459Gg72Rd14POeUOzmp8-cQWSduGmV_0MqeB7YTPSuM95EAkCAXs0zrIKK3OIcMuW2Hvp471QvSPwP29JVuNle6EJTC9F2FUflAmCkjP3vIOPNXcNtDQhTCV-b3v8CDjzbK0L_yGPXMGgSI3dPN5HDKtTIKNqPuchL4UtmTMZPdQ4bdbcBXJI35CFoS2cHPBm_m5GgemZSrG8LwQCbZuVYTimcWmLJX4FJLsZisVmewggis8gTtHHWenx_Xs2FSA-p9i5ik3TGxDEz9qhYry_C3l47E9w4-q_sBQo670AzX1ozD9aU8c7BpMquUSIaTbU5S2cNp_AD0_tswLB1rgPBlm5mu87rLn8m-ue0WaW1hDsCln4JBSIlo_aqyWfcwm_jUfyWrrBKIpfo1m9xugVT3hTuw_2D1LIxU3Ve8S62wLJLCJczYf8HbaPEsIIM4qwu9bGPFYPEBca8Vv4Q_mmpbdniDJ_2TNlV5-6ZBZ5Bun6XwiTe4q7muSFuugT_w5CY3EghYrxKZqBOeHPMSzthJ_qPZQGzO38bm4ipk0CmHQ_pn_OzCnsdRTY4ncLT6CDCnTeB6Lg5dUOzFgYN4l2P9y9g3eVaACBq7sUMkEF24PEX2uK6kBpwpiaTEZlZUa4m1jjUeAuLveOiBuZLtRRmiX5BeNDaoZl9B7cKavZYNOizgr-d8Kpq7aBzZ49i208zsEvzT157YcThkmxV8S82854SGZrhyB9CxtJnUafDVqJCr5k3tILP8ynU8Rev8p1XptlFtZ2jmisN2dHrq4D2fdqdwEDGqzFGOJtVeMHttJM3N8dS8ChnFr5i4NlBi2omRSWnh-em2ma3UO7TFLkMB2QKWZdLEgwP-efhTHuallg_rCibwQYHrgaGAa1-KyWOVrwg3WIw3-vcS_5-Nicl0k3OCVtRROGHVsr8DQQJL_HoQl2_UH71KNma8UipB9J6r5tS7XEvLxmfP9RRJAhlrtkp67Kv05BL1BO0tDADJ_r9A0VAy1pVOtjds_rtsne89hF4RJtMKLiSJZQY9-JznZ4CuakObhgLBCFa4st8blrAg-Ug5rKC-ECGi3CxtSm9S_a2V5TPXRW1vSYzT1pPvW36Dy_ARuHrrzQAHfPNCNGnmBazIfsQaa8rk3C9kloffOrxyUge_76GCRD39NcLI6M7AFFJqTrBx8dUH9pjO70OwqUTXzvRMmrOc8rjvEw0p1qEdCBTx73HaZfW9YJTOCM6zLzsbJk5xU3pbxvojqiZA1tYJM0CsDLvUHPuiP6LB3n2bsrel9MeaSxd9Z_0Crscg7Iu-0koml9pBDDFrAdLGf3BvHnE2mYwQ5NSlsoAsCSUM-frec85CH7ak25VayvPMvR6RiHzT0L3olpoM_VxkhAy9NDVBm_NytsZ6y9yjaAi2nQlzkIXBNMygOeasc4ivT9uSyyDRwehAlx41e_a5yWHZPHVFqsD7AbfCi98mnDv42DSvTtQ0PX_pLCBitfKrxuWPA-arxiQRxa2q0VQ7h5WKoZL_B_bhNhHJvb4qNpZlw904TQan-RzgOG_QHRs7j-wommXyaoIh4HL_jWcV-UHciRL5KtsCzrE0RaXVzfVmZq5Td__FHblebHwokPFP2grNsGG9lLkA7SDUOXcF4ZjAJ88-HKnryVsR58LDOkUlDVk3fqTruyHKqcdQmnNrkHXQPY4-mtS30qBo0508a4Y2ER868WZ5-ZBRVPRY_Hq8iJ6u1NW4TMjl6KrwPsLcGgMx8NgrnENTYcYGXeS6GNTpLwQStTynZJT9pn8T8zXH6B3iUdvIJ0Do6PDcocChiTrIZPChtUhVdZ1d2Xdxk__KJUJjtjwXCxJLNzSoOJPOBTCGgpUEdH0m56M-JtEXJWh0FEwVjQrA0QGl510fJrbzYEantSPg8weGD_FvkI9zsh4YfNEZfzyepunDESgJnkl2DBE4CHeJzoB2DoM3CahPcq3VzhEQkvAh7c-PLWZOjQg0jkjE-O5YC5f6y6ingGfie2XaJwvPiHWsgDrSrnyMoJSUp12pJaHKDtfKmP67DNdmpNtA4WwSn_-ofJAXziAFHF4YmqdrOXNNGz8VibgIrIZojNEohvKyMkC_I3Oh0JlULLRqhPm7WXZAtcNI_IaVFNCivxThvt6sg0ngF0hAh-DcjDbgFzGFSlbH2aZ4vEsCnInf1ymy1CHoICqCBg1IySTtSAAiGRqfo6gl2E3WYgNgQ-O2r1UwQ50_cMlRjyEEYR4MF2Cu8-oBi0ovZ2LwGvUk0M8EofMGLxIIPl-8B3CDGa69kquHe8ohWKLLFOEnkVFC-capctlK02pmsh7zCGIp-lFxJhdQLgdEII_I7AVgdNxLvybI0M9EeLRDrdHeSeNAaeKr6uwsezA1kppe8IAnEbEDxyrSLpF2E4b5sSVfzW3PU7nAelt6_sOy_s18mKJFRjw-kImiGZZnZvwycvAPTFkub7Od44JjeNnDIB4H3Z85Kr-pviSh-quaxVrN5zSKaYH32KgCUwb3GJ4q1Id08_laD7Gz9_pJhZSck2ZpntBXQxT8UZkcdZ7_HgHvz03P8jN-cRMg902xKjwTZqBzfzPwL7G016Y-dwexR4BTD4-8i8Sfbm2DMVuFwWrfVcOs3d_ShArko1Zq_pkur8Ae7gYdvxkl1Bg9EiflqhDgUtEeERDEuryqfz_7OQ8EbgQd82zmxDVttgJA0yx-CMLgz30HYkzG82vtrDPcjR6h3seZti_IwbDM2Su-daOWWsjxbR7ezPivcsjpfrlarDG5pLkPTwEeF-zL_cns3fsVnPMwXpIsSDWHUdLRlqCixoDPuRhM5wovrQA0wDbwPj-aOr9gdhUmEWVj4Usi6sLRQZgTGullN0XWU4Mw9BEa9j1mqt5aQUE17Dr_g_yojMdZIE6uvfGQpEmoFiksrldXqiXTFncST1wZ-NBDXEQ.dx2FojOO5a37TLYCTucI-LVAFHKqeOA8ckqhFE7aAHY\",\"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\":1776120188352},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyMTY4OSwiaWF0IjoxNzc2MTE4Mzg5LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiJjMDgxNjFjNy1iZGYyLTQzZDktYTU4NC1lMmMwMGU4ZjhhYzIiLCJhdF9oYXNoIjoiUU0wbFl5N3lscDJYaklzcE44Nml4QSJ9.JsmF2b9wT9RWpueWEWklgUnSF1845zNHPMEdI0q4mn5PUXfye4VlTw99kMYUiSANSAi5r1xOa6LN6qLhkNsuUqNJ7otXidIiIGeaZk98uvzv9dGCm0wmWbwnIe-Nb7uY01kUXhOtNYzIm5uXzyK42H-FdDNAAURZCgxOMCW4wSmcSYN9PUp1n-E2O3aNnZFZf3007wT_7ydFvZGrHTf2bIxwECuLxG6mwwETwqHlbzvMGB17SmxatSP4ORG15Y7n2Bs3vrjsRZf8T_lcjvF4zGpy9GpuMSKowPbo0O725BILTt0Jm97qpSCXnS6kX1vkaRlVacVQrWCxsGzVm0VK6A\"},\"dpopKeyThumbprint\":\"aYSFNjC9Y9T7vkH2fWx7GwayGTrfiLoqt-WUBwWgF8o\",\"issuedAtEpochMs\":1776118389353,\"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\":1776118389000,\"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}" + ], + [ + "stellaops.theme", + "system" + ], + [ + "stellaops.auth.session.info", + "{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"expiresAtEpochMs\":1776120188352,\"issuedAtEpochMs\":1776118389353,\"dpopKeyThumbprint\":\"aYSFNjC9Y9T7vkH2fWx7GwayGTrfiLoqt-WUBwWgF8o\",\"tenantId\":\"demo-prod\"}" + ], + [ + "stellaops.sidebar.preferences", + "{\"sidebarCollapsed\":false,\"collapsedGroups\":[\"evidence\",\"setup-admin\"],\"collapsedSections\":[]}" + ] + ], + "sessionStorageEntries": [ + [ + "stellaops.auth.session.full", + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyMDE4OSwiaWF0IjoxNzc2MTE4Mzg5LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiYmViOGVlMDktN2MyNy00MDBhLTk2ZjctMWNjMTA0NTY3MzVjIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMTgzODksIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.ciSQoX-EVPzXeOivFZum8P5G0yYkfS6q-rx4-HRnYHnZUnaZ0SEPWH5vd7Qtf1kR1EXGsyl1ppzsJeHVMRVtjoFJ7mwVq4Mqk89HDsm1Jbbz8EfuXQqZ5BQxpUl0-tZH142p_HekeL52xN9vM7NT80NN-dHyQqhYvjtnSv6uHDopeeawG9KXhV3c0v8QpDHNLbisjTXDOACxqHaboM6h8Iu9c83avxOIdwym403gWz9iXFvCeh5AzivaTK3RuQXsM_9J3b-TujVlD3jMQpcC9Z2Gzf8krpLw7fSfZq84EXVNpV6Cp3M_TkxpwdSN_OLK6gl8Aej2d1Sdsn2mFGWSzw\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.Ei7-g6G7vxB34iNHdxJIg0KPsdcBY9V36ImTrCGzPTNavYtTqWLPI6gj5ZV02E080HVJBUpavMmnvVYN1OR97mR1xnU206zh62c3HC1-w2b4wJHIrYvmnays0Bq9cvrTfWJTzkBzUTEOoylf2rP_Rl0Uvqn1OzwsRIudqtryOcJRlqpNQSAzHPgKj6AynMe_KvrtWv76Lib2yTmuEdKG3rcbDma6x85nrnuk3TCCGz4RTfuh8aU0IdHOc58AyS2UiN0hIuIkNwSK4rFije_PiWb4uPuQg-58aGnkywuI78cAKTOWLKw3F5i_q_TGBtXJLYnoWfpCs6cUjtU2OMM1zg.3s9xbQLNa93wCujW_wDJqQ.9i_U_HN-KpAQWzVYY4oczfbyJ3WfRV-yIO1oGX9OW0wvsbGauH4eiw_iGGawKJb8jVHqVIRlM17lttPKJylitVeVB5fddryi5T7zkRf2uPo9RWw0tievVA-0jSLr1fOAvBS228lnJB0qjcb5n-C376_nEtx_jjcHVe35n7Mh--ZRIGIHyE3z_H6fgEcu6dvW-agaHxx4qmdWd7hostUiO1wlGaajeA4ntfAey5jHHy5ysChJdG-blICOA73ibKoDXoec4B8f0fEMLlR1iLbplcFZNG1BKDKNsKdKABPWBrh9Qve0HX5e41H1Mzby9Sk6Ph1QUMn0OiNeSKqYPMF8ovoQJq8Ouss1Dfcow_QqFj8ScmIss4aex_Uf1fkg-eIbda-woYAJcOZvKN4wTZNZZbd2gTpL_t0Ul7PYwk7B_1SZUO9Mi9H76PzI236wQYaXAN-u9QZfLSfNUfy5ive-dSoSE6vgK8ho334Bt2F7uMwS4JGNDLdeiNn8KrYvhfyK6k2xz2ZD073qkXP5h9qO3TCE5SndlleC_sRqhiYlYjbEI_EFwN4bP7OBdnwfUx9-JFwf6SeMrq2HPy0gs4081NT-YKEMWdo5LLrzQ83vR6mHadXYYHV42vTdisrVNbSko_rzVsFTINqFgq3JyEGMJo-eOTKQvuV415-CZPpewwyt-o5Q4N5Mee4zJXfrpR0ZNx4ebTph97PCZRZm2UrPkmrP8wRDIjj4dksXFSYfsjQ3DIP_-mQ7mLkg6CFXL8GTqw8E7RiOPn14L1V7CTgUcUOxZYgE9Ctxu48npb3v0W-nVcmYHkgAVOHGOdf93AbE6x3giz6ASS9MKWJ_asZ8zvA4bYV_DNMteE9MXZVXnPLyCOaGhRhQNpfMqsBK5yjEKzIAMjKdKh0KxnGQQMERohesPT-miIDZRIBiMlF7gM3vWx9XIUfoGw2KIcja9UZkN4I3qOrQS1S-2ZNptIJMphwnXqeKj_9xWBkgGXIEICo2pVA2vM3qFWdIjtbevuEhisV-cdhCtAmPh7yYoj5JTTTfKWedJQX5e0Zqfhlo8CtZcmFDTyTmb0aN_UgQ9BvxgqIfxAT6ndWZm0ofZO2rekBERRtGVxz1EUdbsv76gjEkb2ZZqOLq8K-n6E3oqwNgNuuxy9NVUkEqx8vCO5jAtJS-xZrB3d59eh1oqC0sF1GLdat6ULU_Zigh-mbnNFR-7lyjPpHGK16a_T10VBur629NLNJunfx8om6T1V_kWfPp9MJIfinSMIAFrbxSch1UcY_KjvIFJV95LFv5VpnP-wsd9LAmGo2NstouF9BSfaa-WB6KmRfA1pIO7-CIamdr2h5hO3PLML-AlXHFY1_bi-b_U9h52adzZG5meto1eky7v8bOkX1DeK9LQMy5MVYj8roiurG9SwhcZc3B3f-4UAKoh5lFDUoDK1w7bn1QPoD2aGQ0hUBB-D9Esh_m4MlDO5zO92q9Yg2WB6I_gAoojWWa0PeLJzlxJ42W4hO7mLqd1Zqoik_RHB1gO5PEhnehx5pzv4UAI-s-hOJ5LV_RrVBuX5GQFuz4OI9G9s06Tu9KyLGSu2y-woJ9C5-US25CbhTjwXtoHuYIIVR5lF8ghKCIuZZCYXuw8-K15K5gPTdkjiMcNp3yCm22jTwiM6lK3m5sj261VPtrIe7WqJkNf9YTaKCW-FTj7lDF-lVYqpkccgWxiOdyNG661JRtONpW6Tm2BVTt7DWfR31QcVGrBZA0J8xs-udj10SHi9AKHnj3tVrtUbd2n5nYqI7W9v6t6E9VBUa--fth459Gg72Rd14POeUOzmp8-cQWSduGmV_0MqeB7YTPSuM95EAkCAXs0zrIKK3OIcMuW2Hvp471QvSPwP29JVuNle6EJTC9F2FUflAmCkjP3vIOPNXcNtDQhTCV-b3v8CDjzbK0L_yGPXMGgSI3dPN5HDKtTIKNqPuchL4UtmTMZPdQ4bdbcBXJI35CFoS2cHPBm_m5GgemZSrG8LwQCbZuVYTimcWmLJX4FJLsZisVmewggis8gTtHHWenx_Xs2FSA-p9i5ik3TGxDEz9qhYry_C3l47E9w4-q_sBQo670AzX1ozD9aU8c7BpMquUSIaTbU5S2cNp_AD0_tswLB1rgPBlm5mu87rLn8m-ue0WaW1hDsCln4JBSIlo_aqyWfcwm_jUfyWrrBKIpfo1m9xugVT3hTuw_2D1LIxU3Ve8S62wLJLCJczYf8HbaPEsIIM4qwu9bGPFYPEBca8Vv4Q_mmpbdniDJ_2TNlV5-6ZBZ5Bun6XwiTe4q7muSFuugT_w5CY3EghYrxKZqBOeHPMSzthJ_qPZQGzO38bm4ipk0CmHQ_pn_OzCnsdRTY4ncLT6CDCnTeB6Lg5dUOzFgYN4l2P9y9g3eVaACBq7sUMkEF24PEX2uK6kBpwpiaTEZlZUa4m1jjUeAuLveOiBuZLtRRmiX5BeNDaoZl9B7cKavZYNOizgr-d8Kpq7aBzZ49i208zsEvzT157YcThkmxV8S82854SGZrhyB9CxtJnUafDVqJCr5k3tILP8ynU8Rev8p1XptlFtZ2jmisN2dHrq4D2fdqdwEDGqzFGOJtVeMHttJM3N8dS8ChnFr5i4NlBi2omRSWnh-em2ma3UO7TFLkMB2QKWZdLEgwP-efhTHuallg_rCibwQYHrgaGAa1-KyWOVrwg3WIw3-vcS_5-Nicl0k3OCVtRROGHVsr8DQQJL_HoQl2_UH71KNma8UipB9J6r5tS7XEvLxmfP9RRJAhlrtkp67Kv05BL1BO0tDADJ_r9A0VAy1pVOtjds_rtsne89hF4RJtMKLiSJZQY9-JznZ4CuakObhgLBCFa4st8blrAg-Ug5rKC-ECGi3CxtSm9S_a2V5TPXRW1vSYzT1pPvW36Dy_ARuHrrzQAHfPNCNGnmBazIfsQaa8rk3C9kloffOrxyUge_76GCRD39NcLI6M7AFFJqTrBx8dUH9pjO70OwqUTXzvRMmrOc8rjvEw0p1qEdCBTx73HaZfW9YJTOCM6zLzsbJk5xU3pbxvojqiZA1tYJM0CsDLvUHPuiP6LB3n2bsrel9MeaSxd9Z_0Crscg7Iu-0koml9pBDDFrAdLGf3BvHnE2mYwQ5NSlsoAsCSUM-frec85CH7ak25VayvPMvR6RiHzT0L3olpoM_VxkhAy9NDVBm_NytsZ6y9yjaAi2nQlzkIXBNMygOeasc4ivT9uSyyDRwehAlx41e_a5yWHZPHVFqsD7AbfCi98mnDv42DSvTtQ0PX_pLCBitfKrxuWPA-arxiQRxa2q0VQ7h5WKoZL_B_bhNhHJvb4qNpZlw904TQan-RzgOG_QHRs7j-wommXyaoIh4HL_jWcV-UHciRL5KtsCzrE0RaXVzfVmZq5Td__FHblebHwokPFP2grNsGG9lLkA7SDUOXcF4ZjAJ88-HKnryVsR58LDOkUlDVk3fqTruyHKqcdQmnNrkHXQPY4-mtS30qBo0508a4Y2ER868WZ5-ZBRVPRY_Hq8iJ6u1NW4TMjl6KrwPsLcGgMx8NgrnENTYcYGXeS6GNTpLwQStTynZJT9pn8T8zXH6B3iUdvIJ0Do6PDcocChiTrIZPChtUhVdZ1d2Xdxk__KJUJjtjwXCxJLNzSoOJPOBTCGgpUEdH0m56M-JtEXJWh0FEwVjQrA0QGl510fJrbzYEantSPg8weGD_FvkI9zsh4YfNEZfzyepunDESgJnkl2DBE4CHeJzoB2DoM3CahPcq3VzhEQkvAh7c-PLWZOjQg0jkjE-O5YC5f6y6ingGfie2XaJwvPiHWsgDrSrnyMoJSUp12pJaHKDtfKmP67DNdmpNtA4WwSn_-ofJAXziAFHF4YmqdrOXNNGz8VibgIrIZojNEohvKyMkC_I3Oh0JlULLRqhPm7WXZAtcNI_IaVFNCivxThvt6sg0ngF0hAh-DcjDbgFzGFSlbH2aZ4vEsCnInf1ymy1CHoICqCBg1IySTtSAAiGRqfo6gl2E3WYgNgQ-O2r1UwQ50_cMlRjyEEYR4MF2Cu8-oBi0ovZ2LwGvUk0M8EofMGLxIIPl-8B3CDGa69kquHe8ohWKLLFOEnkVFC-capctlK02pmsh7zCGIp-lFxJhdQLgdEII_I7AVgdNxLvybI0M9EeLRDrdHeSeNAaeKr6uwsezA1kppe8IAnEbEDxyrSLpF2E4b5sSVfzW3PU7nAelt6_sOy_s18mKJFRjw-kImiGZZnZvwycvAPTFkub7Od44JjeNnDIB4H3Z85Kr-pviSh-quaxVrN5zSKaYH32KgCUwb3GJ4q1Id08_laD7Gz9_pJhZSck2ZpntBXQxT8UZkcdZ7_HgHvz03P8jN-cRMg902xKjwTZqBzfzPwL7G016Y-dwexR4BTD4-8i8Sfbm2DMVuFwWrfVcOs3d_ShArko1Zq_pkur8Ae7gYdvxkl1Bg9EiflqhDgUtEeERDEuryqfz_7OQ8EbgQd82zmxDVttgJA0yx-CMLgz30HYkzG82vtrDPcjR6h3seZti_IwbDM2Su-daOWWsjxbR7ezPivcsjpfrlarDG5pLkPTwEeF-zL_cns3fsVnPMwXpIsSDWHUdLRlqCixoDPuRhM5wovrQA0wDbwPj-aOr9gdhUmEWVj4Usi6sLRQZgTGullN0XWU4Mw9BEa9j1mqt5aQUE17Dr_g_yojMdZIE6uvfGQpEmoFiksrldXqiXTFncST1wZ-NBDXEQ.dx2FojOO5a37TLYCTucI-LVAFHKqeOA8ckqhFE7aAHY\",\"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\":1776120188352},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyMTY4OSwiaWF0IjoxNzc2MTE4Mzg5LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiJjMDgxNjFjNy1iZGYyLTQzZDktYTU4NC1lMmMwMGU4ZjhhYzIiLCJhdF9oYXNoIjoiUU0wbFl5N3lscDJYaklzcE44Nml4QSJ9.JsmF2b9wT9RWpueWEWklgUnSF1845zNHPMEdI0q4mn5PUXfye4VlTw99kMYUiSANSAi5r1xOa6LN6qLhkNsuUqNJ7otXidIiIGeaZk98uvzv9dGCm0wmWbwnIe-Nb7uY01kUXhOtNYzIm5uXzyK42H-FdDNAAURZCgxOMCW4wSmcSYN9PUp1n-E2O3aNnZFZf3007wT_7ydFvZGrHTf2bIxwECuLxG6mwwETwqHlbzvMGB17SmxatSP4ORG15Y7n2Bs3vrjsRZf8T_lcjvF4zGpy9GpuMSKowPbo0O725BILTt0Jm97qpSCXnS6kX1vkaRlVacVQrWCxsGzVm0VK6A\"},\"dpopKeyThumbprint\":\"aYSFNjC9Y9T7vkH2fWx7GwayGTrfiLoqt-WUBwWgF8o\",\"issuedAtEpochMs\":1776118389353,\"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\":1776118389000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" + ], + [ + "stellaops:wasEverAuth", + "true" + ] + ] + }, + "events": { + "consoleErrors": [ + "Failed to load resource: the server responded with a status of 503 ()", + "Failed to load resource: the server responded with a status of 503 ()", + "Failed to load resource: the server responded with a status of 503 ()", + "Failed to load resource: the server responded with a status of 503 ()" + ], + "requestFailures": [], + "responseErrors": [ + { + "status": 503, + "method": "GET", + "url": "https://stella-ops.local/api/v1/scheduler/doctor/trends/categories/security?from=2025-04-18T22:13:09.398Z&to=2026-04-13T22:13:09.398Z", + "page": "https://stella-ops.local/" + }, + { + "status": 503, + "method": "GET", + "url": "https://stella-ops.local/api/v1/scheduler/doctor/trends/categories/platform?from=2025-04-18T22:13:09.398Z&to=2026-04-13T22:13:09.398Z", + "page": "https://stella-ops.local/" + }, + { + "status": 503, + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "page": "https://stella-ops.local/" + }, + { + "status": 503, + "method": "GET", + "url": "https://stella-ops.local/api/v1/vulnerabilities/status", + "page": "https://stella-ops.local/" + } + ] + }, + "statePath": "src/Web/StellaOps.Web/output/playwright/live-setup-wizard-probe.state.json" +} diff --git a/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-probe.state.json b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-probe.state.json new file mode 100644 index 000000000..df2428e4a --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-probe.state.json @@ -0,0 +1,38 @@ +{ + "cookies": [], + "origins": [ + { + "origin": "https://stella-ops.local", + "localStorage": [ + { + "name": "stellaops.auth.session.full", + "value": "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyMDE4OSwiaWF0IjoxNzc2MTE4Mzg5LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiYmViOGVlMDktN2MyNy00MDBhLTk2ZjctMWNjMTA0NTY3MzVjIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMTgzODksIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.ciSQoX-EVPzXeOivFZum8P5G0yYkfS6q-rx4-HRnYHnZUnaZ0SEPWH5vd7Qtf1kR1EXGsyl1ppzsJeHVMRVtjoFJ7mwVq4Mqk89HDsm1Jbbz8EfuXQqZ5BQxpUl0-tZH142p_HekeL52xN9vM7NT80NN-dHyQqhYvjtnSv6uHDopeeawG9KXhV3c0v8QpDHNLbisjTXDOACxqHaboM6h8Iu9c83avxOIdwym403gWz9iXFvCeh5AzivaTK3RuQXsM_9J3b-TujVlD3jMQpcC9Z2Gzf8krpLw7fSfZq84EXVNpV6Cp3M_TkxpwdSN_OLK6gl8Aej2d1Sdsn2mFGWSzw\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.Ei7-g6G7vxB34iNHdxJIg0KPsdcBY9V36ImTrCGzPTNavYtTqWLPI6gj5ZV02E080HVJBUpavMmnvVYN1OR97mR1xnU206zh62c3HC1-w2b4wJHIrYvmnays0Bq9cvrTfWJTzkBzUTEOoylf2rP_Rl0Uvqn1OzwsRIudqtryOcJRlqpNQSAzHPgKj6AynMe_KvrtWv76Lib2yTmuEdKG3rcbDma6x85nrnuk3TCCGz4RTfuh8aU0IdHOc58AyS2UiN0hIuIkNwSK4rFije_PiWb4uPuQg-58aGnkywuI78cAKTOWLKw3F5i_q_TGBtXJLYnoWfpCs6cUjtU2OMM1zg.3s9xbQLNa93wCujW_wDJqQ.9i_U_HN-KpAQWzVYY4oczfbyJ3WfRV-yIO1oGX9OW0wvsbGauH4eiw_iGGawKJb8jVHqVIRlM17lttPKJylitVeVB5fddryi5T7zkRf2uPo9RWw0tievVA-0jSLr1fOAvBS228lnJB0qjcb5n-C376_nEtx_jjcHVe35n7Mh--ZRIGIHyE3z_H6fgEcu6dvW-agaHxx4qmdWd7hostUiO1wlGaajeA4ntfAey5jHHy5ysChJdG-blICOA73ibKoDXoec4B8f0fEMLlR1iLbplcFZNG1BKDKNsKdKABPWBrh9Qve0HX5e41H1Mzby9Sk6Ph1QUMn0OiNeSKqYPMF8ovoQJq8Ouss1Dfcow_QqFj8ScmIss4aex_Uf1fkg-eIbda-woYAJcOZvKN4wTZNZZbd2gTpL_t0Ul7PYwk7B_1SZUO9Mi9H76PzI236wQYaXAN-u9QZfLSfNUfy5ive-dSoSE6vgK8ho334Bt2F7uMwS4JGNDLdeiNn8KrYvhfyK6k2xz2ZD073qkXP5h9qO3TCE5SndlleC_sRqhiYlYjbEI_EFwN4bP7OBdnwfUx9-JFwf6SeMrq2HPy0gs4081NT-YKEMWdo5LLrzQ83vR6mHadXYYHV42vTdisrVNbSko_rzVsFTINqFgq3JyEGMJo-eOTKQvuV415-CZPpewwyt-o5Q4N5Mee4zJXfrpR0ZNx4ebTph97PCZRZm2UrPkmrP8wRDIjj4dksXFSYfsjQ3DIP_-mQ7mLkg6CFXL8GTqw8E7RiOPn14L1V7CTgUcUOxZYgE9Ctxu48npb3v0W-nVcmYHkgAVOHGOdf93AbE6x3giz6ASS9MKWJ_asZ8zvA4bYV_DNMteE9MXZVXnPLyCOaGhRhQNpfMqsBK5yjEKzIAMjKdKh0KxnGQQMERohesPT-miIDZRIBiMlF7gM3vWx9XIUfoGw2KIcja9UZkN4I3qOrQS1S-2ZNptIJMphwnXqeKj_9xWBkgGXIEICo2pVA2vM3qFWdIjtbevuEhisV-cdhCtAmPh7yYoj5JTTTfKWedJQX5e0Zqfhlo8CtZcmFDTyTmb0aN_UgQ9BvxgqIfxAT6ndWZm0ofZO2rekBERRtGVxz1EUdbsv76gjEkb2ZZqOLq8K-n6E3oqwNgNuuxy9NVUkEqx8vCO5jAtJS-xZrB3d59eh1oqC0sF1GLdat6ULU_Zigh-mbnNFR-7lyjPpHGK16a_T10VBur629NLNJunfx8om6T1V_kWfPp9MJIfinSMIAFrbxSch1UcY_KjvIFJV95LFv5VpnP-wsd9LAmGo2NstouF9BSfaa-WB6KmRfA1pIO7-CIamdr2h5hO3PLML-AlXHFY1_bi-b_U9h52adzZG5meto1eky7v8bOkX1DeK9LQMy5MVYj8roiurG9SwhcZc3B3f-4UAKoh5lFDUoDK1w7bn1QPoD2aGQ0hUBB-D9Esh_m4MlDO5zO92q9Yg2WB6I_gAoojWWa0PeLJzlxJ42W4hO7mLqd1Zqoik_RHB1gO5PEhnehx5pzv4UAI-s-hOJ5LV_RrVBuX5GQFuz4OI9G9s06Tu9KyLGSu2y-woJ9C5-US25CbhTjwXtoHuYIIVR5lF8ghKCIuZZCYXuw8-K15K5gPTdkjiMcNp3yCm22jTwiM6lK3m5sj261VPtrIe7WqJkNf9YTaKCW-FTj7lDF-lVYqpkccgWxiOdyNG661JRtONpW6Tm2BVTt7DWfR31QcVGrBZA0J8xs-udj10SHi9AKHnj3tVrtUbd2n5nYqI7W9v6t6E9VBUa--fth459Gg72Rd14POeUOzmp8-cQWSduGmV_0MqeB7YTPSuM95EAkCAXs0zrIKK3OIcMuW2Hvp471QvSPwP29JVuNle6EJTC9F2FUflAmCkjP3vIOPNXcNtDQhTCV-b3v8CDjzbK0L_yGPXMGgSI3dPN5HDKtTIKNqPuchL4UtmTMZPdQ4bdbcBXJI35CFoS2cHPBm_m5GgemZSrG8LwQCbZuVYTimcWmLJX4FJLsZisVmewggis8gTtHHWenx_Xs2FSA-p9i5ik3TGxDEz9qhYry_C3l47E9w4-q_sBQo670AzX1ozD9aU8c7BpMquUSIaTbU5S2cNp_AD0_tswLB1rgPBlm5mu87rLn8m-ue0WaW1hDsCln4JBSIlo_aqyWfcwm_jUfyWrrBKIpfo1m9xugVT3hTuw_2D1LIxU3Ve8S62wLJLCJczYf8HbaPEsIIM4qwu9bGPFYPEBca8Vv4Q_mmpbdniDJ_2TNlV5-6ZBZ5Bun6XwiTe4q7muSFuugT_w5CY3EghYrxKZqBOeHPMSzthJ_qPZQGzO38bm4ipk0CmHQ_pn_OzCnsdRTY4ncLT6CDCnTeB6Lg5dUOzFgYN4l2P9y9g3eVaACBq7sUMkEF24PEX2uK6kBpwpiaTEZlZUa4m1jjUeAuLveOiBuZLtRRmiX5BeNDaoZl9B7cKavZYNOizgr-d8Kpq7aBzZ49i208zsEvzT157YcThkmxV8S82854SGZrhyB9CxtJnUafDVqJCr5k3tILP8ynU8Rev8p1XptlFtZ2jmisN2dHrq4D2fdqdwEDGqzFGOJtVeMHttJM3N8dS8ChnFr5i4NlBi2omRSWnh-em2ma3UO7TFLkMB2QKWZdLEgwP-efhTHuallg_rCibwQYHrgaGAa1-KyWOVrwg3WIw3-vcS_5-Nicl0k3OCVtRROGHVsr8DQQJL_HoQl2_UH71KNma8UipB9J6r5tS7XEvLxmfP9RRJAhlrtkp67Kv05BL1BO0tDADJ_r9A0VAy1pVOtjds_rtsne89hF4RJtMKLiSJZQY9-JznZ4CuakObhgLBCFa4st8blrAg-Ug5rKC-ECGi3CxtSm9S_a2V5TPXRW1vSYzT1pPvW36Dy_ARuHrrzQAHfPNCNGnmBazIfsQaa8rk3C9kloffOrxyUge_76GCRD39NcLI6M7AFFJqTrBx8dUH9pjO70OwqUTXzvRMmrOc8rjvEw0p1qEdCBTx73HaZfW9YJTOCM6zLzsbJk5xU3pbxvojqiZA1tYJM0CsDLvUHPuiP6LB3n2bsrel9MeaSxd9Z_0Crscg7Iu-0koml9pBDDFrAdLGf3BvHnE2mYwQ5NSlsoAsCSUM-frec85CH7ak25VayvPMvR6RiHzT0L3olpoM_VxkhAy9NDVBm_NytsZ6y9yjaAi2nQlzkIXBNMygOeasc4ivT9uSyyDRwehAlx41e_a5yWHZPHVFqsD7AbfCi98mnDv42DSvTtQ0PX_pLCBitfKrxuWPA-arxiQRxa2q0VQ7h5WKoZL_B_bhNhHJvb4qNpZlw904TQan-RzgOG_QHRs7j-wommXyaoIh4HL_jWcV-UHciRL5KtsCzrE0RaXVzfVmZq5Td__FHblebHwokPFP2grNsGG9lLkA7SDUOXcF4ZjAJ88-HKnryVsR58LDOkUlDVk3fqTruyHKqcdQmnNrkHXQPY4-mtS30qBo0508a4Y2ER868WZ5-ZBRVPRY_Hq8iJ6u1NW4TMjl6KrwPsLcGgMx8NgrnENTYcYGXeS6GNTpLwQStTynZJT9pn8T8zXH6B3iUdvIJ0Do6PDcocChiTrIZPChtUhVdZ1d2Xdxk__KJUJjtjwXCxJLNzSoOJPOBTCGgpUEdH0m56M-JtEXJWh0FEwVjQrA0QGl510fJrbzYEantSPg8weGD_FvkI9zsh4YfNEZfzyepunDESgJnkl2DBE4CHeJzoB2DoM3CahPcq3VzhEQkvAh7c-PLWZOjQg0jkjE-O5YC5f6y6ingGfie2XaJwvPiHWsgDrSrnyMoJSUp12pJaHKDtfKmP67DNdmpNtA4WwSn_-ofJAXziAFHF4YmqdrOXNNGz8VibgIrIZojNEohvKyMkC_I3Oh0JlULLRqhPm7WXZAtcNI_IaVFNCivxThvt6sg0ngF0hAh-DcjDbgFzGFSlbH2aZ4vEsCnInf1ymy1CHoICqCBg1IySTtSAAiGRqfo6gl2E3WYgNgQ-O2r1UwQ50_cMlRjyEEYR4MF2Cu8-oBi0ovZ2LwGvUk0M8EofMGLxIIPl-8B3CDGa69kquHe8ohWKLLFOEnkVFC-capctlK02pmsh7zCGIp-lFxJhdQLgdEII_I7AVgdNxLvybI0M9EeLRDrdHeSeNAaeKr6uwsezA1kppe8IAnEbEDxyrSLpF2E4b5sSVfzW3PU7nAelt6_sOy_s18mKJFRjw-kImiGZZnZvwycvAPTFkub7Od44JjeNnDIB4H3Z85Kr-pviSh-quaxVrN5zSKaYH32KgCUwb3GJ4q1Id08_laD7Gz9_pJhZSck2ZpntBXQxT8UZkcdZ7_HgHvz03P8jN-cRMg902xKjwTZqBzfzPwL7G016Y-dwexR4BTD4-8i8Sfbm2DMVuFwWrfVcOs3d_ShArko1Zq_pkur8Ae7gYdvxkl1Bg9EiflqhDgUtEeERDEuryqfz_7OQ8EbgQd82zmxDVttgJA0yx-CMLgz30HYkzG82vtrDPcjR6h3seZti_IwbDM2Su-daOWWsjxbR7ezPivcsjpfrlarDG5pLkPTwEeF-zL_cns3fsVnPMwXpIsSDWHUdLRlqCixoDPuRhM5wovrQA0wDbwPj-aOr9gdhUmEWVj4Usi6sLRQZgTGullN0XWU4Mw9BEa9j1mqt5aQUE17Dr_g_yojMdZIE6uvfGQpEmoFiksrldXqiXTFncST1wZ-NBDXEQ.dx2FojOO5a37TLYCTucI-LVAFHKqeOA8ckqhFE7aAHY\",\"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\":1776120188352},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyMTY4OSwiaWF0IjoxNzc2MTE4Mzg5LCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiJjMDgxNjFjNy1iZGYyLTQzZDktYTU4NC1lMmMwMGU4ZjhhYzIiLCJhdF9oYXNoIjoiUU0wbFl5N3lscDJYaklzcE44Nml4QSJ9.JsmF2b9wT9RWpueWEWklgUnSF1845zNHPMEdI0q4mn5PUXfye4VlTw99kMYUiSANSAi5r1xOa6LN6qLhkNsuUqNJ7otXidIiIGeaZk98uvzv9dGCm0wmWbwnIe-Nb7uY01kUXhOtNYzIm5uXzyK42H-FdDNAAURZCgxOMCW4wSmcSYN9PUp1n-E2O3aNnZFZf3007wT_7ydFvZGrHTf2bIxwECuLxG6mwwETwqHlbzvMGB17SmxatSP4ORG15Y7n2Bs3vrjsRZf8T_lcjvF4zGpy9GpuMSKowPbo0O725BILTt0Jm97qpSCXnS6kX1vkaRlVacVQrWCxsGzVm0VK6A\"},\"dpopKeyThumbprint\":\"aYSFNjC9Y9T7vkH2fWx7GwayGTrfiLoqt-WUBwWgF8o\",\"issuedAtEpochMs\":1776118389353,\"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\":1776118389000,\"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}" + }, + { + "name": "stellaops.theme", + "value": "system" + }, + { + "name": "stellaops.auth.session.info", + "value": "{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"expiresAtEpochMs\":1776120188352,\"issuedAtEpochMs\":1776118389353,\"dpopKeyThumbprint\":\"aYSFNjC9Y9T7vkH2fWx7GwayGTrfiLoqt-WUBwWgF8o\",\"tenantId\":\"demo-prod\"}" + }, + { + "name": "stellaops.sidebar.preferences", + "value": "{\"sidebarCollapsed\":false,\"collapsedGroups\":[\"evidence\",\"setup-admin\"],\"collapsedSections\":[]}" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-state-truth-check.auth.json b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-state-truth-check.auth.json new file mode 100644 index 000000000..095032c58 --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-state-truth-check.auth.json @@ -0,0 +1,55 @@ +{ + "authenticatedAtUtc": "2026-04-14T04:28:23.811Z", + "baseUrl": "https://stella-ops.local", + "finalUrl": "https://stella-ops.local/?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Dashboard - StellaOps", + "cookies": [], + "storage": { + "localStorageEntries": [ + [ + "stellaops.auth.session.full", + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjE0MjcwMCwiaWF0IjoxNzc2MTQwOTAwLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiN2IxMmNlMjUtNjI1YS00NDNjLTgxNzMtMDE1Njk5ODJmZjY1Iiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxNDA4OTksIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.YQU_wwjA_LpTBu5csRT_TBGWlahpbsTxz10R1RVD0BcA1UnorvY8zHdgA3AOFqf3_CUix_pD4XzzbWaA_PFnQ92uFEayR5V6vnZX_Mi3KKgdXuzItQPUKw21b0jA0WAMI1cOguwthAWGt_Phx2FdjN9g6JzlLbN18WzXSIq6hGZ2OtZUXITC7VFSfw1Sv9WNwergzJ-YhMr-S5AULZZcoPNX8Lv5X_A3Z6Z_qgnXwR2Or9dLEcVi9l0o-m7n74HJFTb34KhkRd2JzEFTbRdLdgc-yyEplx_GP9vKVdB0edflWQRbludVgHQQGt2BrQkjYx2Wllgly0DvQuBq5UJvxA\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.kRqSP9JfPSQcJV_XOHhtS_4UOa_M0JaDeYeZv-HZ-4lnMqQkWZnoqCHVv6AnuxYAmFrBkRsq_GN12eAPTmqsfbxshn7wKV6yw8qlWMtOJAy5W_khjN4GdQCpH_sN4FnIFTewI3VN9YPm9HsY9PRwJFs0hb40ctH7L1GCTiUteTD1EgnTjnZx6jjnBSozIxAN66oG0o1NIPFXOdRyL6086DsDUMzHowm4-Eo4IBkGnHi1nKE2wT75NQCh08ergofZEkfDGp-RFHdVj9Y0j6WByCUCoIHRFg5ip0z8NzDYkktNIKMR450DCwDFf92gXWbQnWaPRrnRHXXMksHZi3nusQ.2kz62Zrx8_7wABZ7fIHHQQ.Gf4AnTZHwvYeUylN9OR0uzR09A5YLSUegAchtGGMd7PRlW-L7O3-lUJv3tS14fEjcXdxPP7PMXKBoQh0n76l8KsWKhT1fGwA9lhAcTeOBq5YfUKViea5hHFgDh1X8D6ncvySn8ARa18fQmbbyqW_hoqxr27w4ObFBVCgsvyon904EZxWy1G9HhBFwVOYJzWlTBKhs0wq3RX_A6tHWVRPC293R1cP8U5uhH8yd4oK2_LN1n-GMlGiY8nAQc5luNHsc7QW7BuPyEQGzhgFlsbi7avC9CEZhMlRZe9k2HDVAFxjAscXGy5c0KU298_pUjL-9v3T7tyHwP1SumdvDK510xfuKITyj3s54R_MEZKcyupr5WoAwc7Iyt3ViwqgHTDZKyUuWSQR79XFsUH7QmCHuUOlRPuS0pSaClu2RFNnKAWOaIT4_4iTKF33AyRZgByQyGlDyI16tWJ92f3l2QVodZFzq2SmwW4AHFZP3Bu2V04_k1acsltk5_jZBlY2MSUkWLWIp9yS4hxuKw3b9fstbOSrQzC1NJu2d8sK_WgTpEoA9qGopms_CObuBDv-BI7949rr3V3i6YAmxXybqKJJiCvVPe9X3tUlsBLBxZPbRCTcFimnPpHG6-u-LN5oH_Rsaczd-Z6rYhnruufPOWjpSUmuJdyeHxO4DS7pRl0qGb9mglx5EMOV0CVJhiFYqSdP13cpAQ2VFsu5Am4RxvBX1paEfGrGRYwbkiVGIb5i51UmF741YvQ1BGBWS53f-B-L3HH1b4i_sfVdjItQ0fbSj2KQdcnXW-lCzUuKp56MMxLyyfGzJ9hAua-uMyZtnf8JvRBPcx4cXsKWHgfm4KpuPW6ko8OCKHV547myhLQMlUJwhkMlx9M1uWvGmZn3gyej2vY6Vd9VyyD5VjsSbkt6RafulHoRI0WB3KW_WRLKdRbK-HVpy87I6JDYn9DHD5e4GLIwUU0j6qS_xlPbdDEP7DFQ37fGMoV1KScqKDNyfGmpdJv6SQls_MFidiITox2au0PO4pwka9iA99bR3eAB1Oas2XzFRqky4wHIpwFMHTuzM9kUNk7tT0OMwZXLNZPqBj7r8jlXQAIDBl6V-DoW2qtSlPj6ssfXnPQ8N0MQWinKfEaUbPrYR9Ii9Q8f9-J_ezU-i0P1p2kEpKPdd-2_ZLM4gGBja1DGqtUhZOU7WPVXuydRgNG_DZBwzIoTNnIRZ8ahBYfDKk5kdzRxrFeXuGSVH5-XoU0ITpy2f8pg3l3Vll5QpWDh6peSqw4ZfrAbs-xCpNByGILmV8A6q37aQA0ouS66l_YkJuIkMlxkfHXOGGjX6vfS_Yu0EmUrCVBn4W_1B-M4nTf4gKTnomP8ip7QF4IaMqUMhbKMuYM6vzp3CjsnXmofi4_VB6l3-czFT2aatOY2QQ4ydRaPLn63i7FxHe8ZiMKevSzcSu2pZ5GoHp-INmujolvk60smAJdnm3MEBLJnDejhLON2_CBVOD22CMmvVRiUw12hJ7xiCIQambE7XlodWRXxHZq-YNP8SaGDXVtzjfcwZqLwc5D2E8P8m3OO8sUICBikRzevvdlv-7GJ0cxEDy5xDRvM9Sob1130fzjyCyijbxNquAAKBq5YYeKxYXvorvowjPMigjGFTlOYimuxVkHPkz3kqMnuy0h6aEwJlHZVqWfUamOpQGo6zmH6WZGSdAygVD9Os0hVB7NJvrRYLIdTFJK_0HLM0TTRx_-UN5zUME-1fnYv9Uuyh4EQ3gTbkL7zUb1RaE4p6SlnGpzEGUF8VKeVVQvK3PhXYVlrLn3j8caBBj0txpbHMaYXEpW_PgnihefzsSOJACb3ER9-e20skCPxeahOlL_f5YxbKDct_TxRTHNwvrVbgNQW6iAdsZVaAltsTqBCiHjfvE86H2-PcoK2n66oTR3FMPVAyepUHZnH-JJy2L52d99_eZDnDSJu4tUWyOK2Ez3YWuFSsgpYBCiBApSvdBiIxFiiygSY5kH88Dn2aVGua8MvnhzXHKfeMvrYR6C-CHOMA-GEpW4EU7KdwPAtxW1_vHY5-2o9RoEQ-NIdJ_xvRDytl5k59GLvLEeQUQiPgvjz-ix3Q0RyECKI_VoEDvz_lLzP-s2v0imwvFuV72E8eNLjPOzgu3LQ9wH9gz_5IwrVaauBmki_cw5Dhl69XIJ91gwbOk25kqlU2FzC2iJ3fKPVW5a-3-YX-q4l-AIl2iu2kHP4mm5MfCAD4ZuTtjJh_2ZSM6IoMRScc3EmfD6AlMjn1UIwG2cy8XvmbowwncZDXnuk66jmgWY3EdJEbIAPUSn6BoAQgGeIv6K-boLG2UVI9X2mgzWVpapxlB4GC0yB2LB0LdEtwOE-ScfJZtpICmsUUTO1RZSAk7qQCBr4-06kfQSneqaISsDQqe37quQev3UuYCZlv66Z2ufa1il-MSGy2Ei0mW5RrcjLCTolN6FRwxUUfMmg_4yNhFHgoRpuyATRkzIb4JQutSfoh49el3RtRm8-XRm_BqAUbzPB6SbF1ZY6rrpdFqf93fY2TPvHYIri4T7gGc_SJhb97XIAqTbm6OTs7xoQrLgjV_SkM7Vbdffhl9mP-Xj03UahxrcG2txUnJkjbEW138ssCmBEyIBeR7bonH0rLjebkft0k3gi-RQmJijFQVUD_48GdlNF-H1KxMXEdwKYkedFeBpWzXrty9pfz6rtB-fD392_nC6_RwggDRMAAANoAL7RYGxqXIY7KRKn8zOcU1FBQuQ5QpBUJttDXbo24k7PqxKOQ5KqnurcYE6WF5ED7r7cauNJ0BIkLVS_T5y-RJ7FdcBmEhpoLyVUfONvRTh4zQ9HSS6A1rRxWF0b0Qy4-3SQ69wLgCqYns4U0Iz-087RORG6J4Hee4ASFEqt7GQd6XHxlIeegCNgiXaad72T5AJS6U5Tw9ylXMERJ3Y7hxyA37yGxxFgmJ6kX5noxZkPae5TGp_6KjcFnNRkysTfWm7E4VHlywsfaAD6iXXB_WSzRZr9NPpr9E11QU1Nbuz3TYJXCdIx9Cd9z2Kr40cbbx2HopRmNIFcvAJeM7S55SQIjC9xFR2gbBJZU4jTNrh2EQBZvss8FJNHuNg7iQA_uStxBUYAgEU1v-jKwzUlaI-zZMOGHNqdnEkmFg3V7u_f7GIbxWTs-hzMbLtpfHD3Q4CChcjhLj5fmNEDwyRmoSNnVmnbBLkrIYMVWW1D5eYaTHB5z9C3r7vj7pNmGU-TdvbvpAKvHTlvAlS91a-9p5SJV9AneJNdSnldHg-UFSeNCUZwfYzO_IyjPLEtIBAjQRw6gb9gYjqYls2W5Cro7YaKgtKp7R9L2i6Vua7lHE87qQkEWvaRrNBplby1nVvyuaSTfR__tzdh0msCUb1YXOUJ1-ORzrbqTn-OeA1FZw01x6mL26vEelT1slIBgVwtrlxhC8IcCLyOr-qZTnB239bRNPYEWvL8862PjsrwSyDwuS-JHpBVSq5Ya-aPAm_puGr9K7P-OAv5o4QX-o2sMEODY3wf5i1qV6eOQrg81x2vPmj3mLCzBa07lEjI3UFett2lWIPiAwjEuRqE2RJLqmLFQG1cyda1eWMjoEL8wVgW__JIJNB__Ms_o7AGpXfKFD5XsjM0XOzix90QBXa1GXkOCJIuKJ_X98u6sR8-K_zc594cCRX0cWd12wBWwsfyuDpuisVssn64anpZo5nFYVFQLOc5KXSl-188gi-WPnzUif2YkNcvCDd-JwfqB7--e4y7r8w9TCRkiaSgsFEXM1kF1f7aGFjWRNfGksAXfPj-L0XBoJLAbgrwbBGf7uDDmvY81L6pHz6am-6ekfCOT7MOYKElo03MaNpJ7EwJpLh0eqUYqcjYvsP80ZuZZmgA9NTCRo4thXsEkuZBEtUidWYpplEt1rQvtv005p2mCLoBq5gItTIADS15U2U8MhKc6lsbh0yVshMp7uS3rjUVx18RpHB15FTSip80kvZaWtFr9ZUYYGPfuoycjBaBlPBwOfTGNeZwj1Qs0W2wXSTyP_Ae0COu0_vBFIzbgs380jeO-Z3nwYiLi3asrnF8ruh_0LHQpoBHgv-SZ49dq1pMlsvH_Z02mCgEMfe5vmz8kG-AC_lLp8phiW1yMG7LLi8TGAh04OtZhkza6T1RAPKmx7TY9HL1vIKOhz18v_IrtD8fPUn70ZZRxXXhOcht9dzi71bA06AmM_u_RJKmWd3N29zct-a_tDXqnJfMJsjm4YST_Bx22L8a2U51MMre8U0iwGJH4rnkRC0K9KTBYtcYf-UvAKWUDETcQdRiLUqKiJn4Y6PtwSwrKz7uv3bGy2czeddkYjlUDACiIeCS8dQZQ1HyaOrMmOWwY64Asv5Ww0fa_v39wIiQ6y3McEWhZpgEYbL85V7X5Mz9xW61E8vqGXNXycFj0AbCZSzLCq6ObcHu3vfrcNbqXf9032pE8MioAHC-frdZreyCJBz9FARDB0kMrW4umr5F4AX3XY3q5Zqo4E-dYIylI4CqXfW_v9pAkuihLJagi00_GcjsH5K81NIoaqXN70GOCC1XtgfRKjjzl81mDcX_hcbkyiiMuP4tU18ht7Td5u3hslMtyz6nxcApSde7FO1RbIT32OuyvRLt9QQn5Q-S3FsvigROHPArwLYeopDwnqlqrMY3pnnN7juzt8HlO4Mng-rOD8YNa8y8kWvpwSi4MEZJQS51wQvdZwidZbIWUXnJ4TbJ6WBPf_pXc0bPRxMvAiOhDxaEih-skg.EZP5ZCcx-7cFTBr-eZrSkUg7WGkteClhq0W620AywpQ\",\"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\":1776142701112},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjE0NDIwMCwiaWF0IjoxNzc2MTQwOTAwLCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiJmM2U5M2Y5OS1hOWJiLTRkYmYtOWRlMi1mZWVkYWJmMDA1OWUiLCJhdF9oYXNoIjoiSXZ3Z1JuQWN6bmhmUFlVYWVjQ2pzUSJ9.OnBsWI1skzWBkONRAGjAgSX2-UEqPoANG_Z8jMs4VHakd38Hgim5NPO39Np3yX2hWNCyiMEsLs3KoMyNcmuvmqNcz36nSMrbspnPbKetnsPwhLcl1y2VzARSJz7AwuEUCKcDFi6fQVRz4WP0yUXxyCEwzWBtRRfU0RpEoDvvXn_gEW5I6Rpt57Pxr6dwjDKXenAlZVepg8W453mmj8Dgbr-MFGb03UewrWDY63kjJZuNqfhuMQH5v-g3oPfh5xX_MQaJPxYbiGGNw2mC2-QU5ZGKSk2ScfrUgVtDtNGKxFGzQeiaFe-EyNTa2qO_6JgxhfnOYyItC-ujQOUNAQ1qzA\"},\"dpopKeyThumbprint\":\"E7rvIabCjI6h8Vr_n2eT6S3VenBwE1SyA3bp19NMsIs\",\"issuedAtEpochMs\":1776140901113,\"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\":1776140899000,\"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}" + ], + [ + "stellaops.theme", + "system" + ], + [ + "stellaops.auth.session.info", + "{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"expiresAtEpochMs\":1776142701112,\"issuedAtEpochMs\":1776140901113,\"dpopKeyThumbprint\":\"E7rvIabCjI6h8Vr_n2eT6S3VenBwE1SyA3bp19NMsIs\",\"tenantId\":\"demo-prod\"}" + ], + [ + "stellaops.sidebar.preferences", + "{\"sidebarCollapsed\":false,\"collapsedGroups\":[\"evidence\",\"setup-admin\"],\"collapsedSections\":[]}" + ] + ], + "sessionStorageEntries": [ + [ + "stellaops.auth.session.full", + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjE0MjcwMCwiaWF0IjoxNzc2MTQwOTAwLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiN2IxMmNlMjUtNjI1YS00NDNjLTgxNzMtMDE1Njk5ODJmZjY1Iiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxNDA4OTksIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.YQU_wwjA_LpTBu5csRT_TBGWlahpbsTxz10R1RVD0BcA1UnorvY8zHdgA3AOFqf3_CUix_pD4XzzbWaA_PFnQ92uFEayR5V6vnZX_Mi3KKgdXuzItQPUKw21b0jA0WAMI1cOguwthAWGt_Phx2FdjN9g6JzlLbN18WzXSIq6hGZ2OtZUXITC7VFSfw1Sv9WNwergzJ-YhMr-S5AULZZcoPNX8Lv5X_A3Z6Z_qgnXwR2Or9dLEcVi9l0o-m7n74HJFTb34KhkRd2JzEFTbRdLdgc-yyEplx_GP9vKVdB0edflWQRbludVgHQQGt2BrQkjYx2Wllgly0DvQuBq5UJvxA\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.kRqSP9JfPSQcJV_XOHhtS_4UOa_M0JaDeYeZv-HZ-4lnMqQkWZnoqCHVv6AnuxYAmFrBkRsq_GN12eAPTmqsfbxshn7wKV6yw8qlWMtOJAy5W_khjN4GdQCpH_sN4FnIFTewI3VN9YPm9HsY9PRwJFs0hb40ctH7L1GCTiUteTD1EgnTjnZx6jjnBSozIxAN66oG0o1NIPFXOdRyL6086DsDUMzHowm4-Eo4IBkGnHi1nKE2wT75NQCh08ergofZEkfDGp-RFHdVj9Y0j6WByCUCoIHRFg5ip0z8NzDYkktNIKMR450DCwDFf92gXWbQnWaPRrnRHXXMksHZi3nusQ.2kz62Zrx8_7wABZ7fIHHQQ.Gf4AnTZHwvYeUylN9OR0uzR09A5YLSUegAchtGGMd7PRlW-L7O3-lUJv3tS14fEjcXdxPP7PMXKBoQh0n76l8KsWKhT1fGwA9lhAcTeOBq5YfUKViea5hHFgDh1X8D6ncvySn8ARa18fQmbbyqW_hoqxr27w4ObFBVCgsvyon904EZxWy1G9HhBFwVOYJzWlTBKhs0wq3RX_A6tHWVRPC293R1cP8U5uhH8yd4oK2_LN1n-GMlGiY8nAQc5luNHsc7QW7BuPyEQGzhgFlsbi7avC9CEZhMlRZe9k2HDVAFxjAscXGy5c0KU298_pUjL-9v3T7tyHwP1SumdvDK510xfuKITyj3s54R_MEZKcyupr5WoAwc7Iyt3ViwqgHTDZKyUuWSQR79XFsUH7QmCHuUOlRPuS0pSaClu2RFNnKAWOaIT4_4iTKF33AyRZgByQyGlDyI16tWJ92f3l2QVodZFzq2SmwW4AHFZP3Bu2V04_k1acsltk5_jZBlY2MSUkWLWIp9yS4hxuKw3b9fstbOSrQzC1NJu2d8sK_WgTpEoA9qGopms_CObuBDv-BI7949rr3V3i6YAmxXybqKJJiCvVPe9X3tUlsBLBxZPbRCTcFimnPpHG6-u-LN5oH_Rsaczd-Z6rYhnruufPOWjpSUmuJdyeHxO4DS7pRl0qGb9mglx5EMOV0CVJhiFYqSdP13cpAQ2VFsu5Am4RxvBX1paEfGrGRYwbkiVGIb5i51UmF741YvQ1BGBWS53f-B-L3HH1b4i_sfVdjItQ0fbSj2KQdcnXW-lCzUuKp56MMxLyyfGzJ9hAua-uMyZtnf8JvRBPcx4cXsKWHgfm4KpuPW6ko8OCKHV547myhLQMlUJwhkMlx9M1uWvGmZn3gyej2vY6Vd9VyyD5VjsSbkt6RafulHoRI0WB3KW_WRLKdRbK-HVpy87I6JDYn9DHD5e4GLIwUU0j6qS_xlPbdDEP7DFQ37fGMoV1KScqKDNyfGmpdJv6SQls_MFidiITox2au0PO4pwka9iA99bR3eAB1Oas2XzFRqky4wHIpwFMHTuzM9kUNk7tT0OMwZXLNZPqBj7r8jlXQAIDBl6V-DoW2qtSlPj6ssfXnPQ8N0MQWinKfEaUbPrYR9Ii9Q8f9-J_ezU-i0P1p2kEpKPdd-2_ZLM4gGBja1DGqtUhZOU7WPVXuydRgNG_DZBwzIoTNnIRZ8ahBYfDKk5kdzRxrFeXuGSVH5-XoU0ITpy2f8pg3l3Vll5QpWDh6peSqw4ZfrAbs-xCpNByGILmV8A6q37aQA0ouS66l_YkJuIkMlxkfHXOGGjX6vfS_Yu0EmUrCVBn4W_1B-M4nTf4gKTnomP8ip7QF4IaMqUMhbKMuYM6vzp3CjsnXmofi4_VB6l3-czFT2aatOY2QQ4ydRaPLn63i7FxHe8ZiMKevSzcSu2pZ5GoHp-INmujolvk60smAJdnm3MEBLJnDejhLON2_CBVOD22CMmvVRiUw12hJ7xiCIQambE7XlodWRXxHZq-YNP8SaGDXVtzjfcwZqLwc5D2E8P8m3OO8sUICBikRzevvdlv-7GJ0cxEDy5xDRvM9Sob1130fzjyCyijbxNquAAKBq5YYeKxYXvorvowjPMigjGFTlOYimuxVkHPkz3kqMnuy0h6aEwJlHZVqWfUamOpQGo6zmH6WZGSdAygVD9Os0hVB7NJvrRYLIdTFJK_0HLM0TTRx_-UN5zUME-1fnYv9Uuyh4EQ3gTbkL7zUb1RaE4p6SlnGpzEGUF8VKeVVQvK3PhXYVlrLn3j8caBBj0txpbHMaYXEpW_PgnihefzsSOJACb3ER9-e20skCPxeahOlL_f5YxbKDct_TxRTHNwvrVbgNQW6iAdsZVaAltsTqBCiHjfvE86H2-PcoK2n66oTR3FMPVAyepUHZnH-JJy2L52d99_eZDnDSJu4tUWyOK2Ez3YWuFSsgpYBCiBApSvdBiIxFiiygSY5kH88Dn2aVGua8MvnhzXHKfeMvrYR6C-CHOMA-GEpW4EU7KdwPAtxW1_vHY5-2o9RoEQ-NIdJ_xvRDytl5k59GLvLEeQUQiPgvjz-ix3Q0RyECKI_VoEDvz_lLzP-s2v0imwvFuV72E8eNLjPOzgu3LQ9wH9gz_5IwrVaauBmki_cw5Dhl69XIJ91gwbOk25kqlU2FzC2iJ3fKPVW5a-3-YX-q4l-AIl2iu2kHP4mm5MfCAD4ZuTtjJh_2ZSM6IoMRScc3EmfD6AlMjn1UIwG2cy8XvmbowwncZDXnuk66jmgWY3EdJEbIAPUSn6BoAQgGeIv6K-boLG2UVI9X2mgzWVpapxlB4GC0yB2LB0LdEtwOE-ScfJZtpICmsUUTO1RZSAk7qQCBr4-06kfQSneqaISsDQqe37quQev3UuYCZlv66Z2ufa1il-MSGy2Ei0mW5RrcjLCTolN6FRwxUUfMmg_4yNhFHgoRpuyATRkzIb4JQutSfoh49el3RtRm8-XRm_BqAUbzPB6SbF1ZY6rrpdFqf93fY2TPvHYIri4T7gGc_SJhb97XIAqTbm6OTs7xoQrLgjV_SkM7Vbdffhl9mP-Xj03UahxrcG2txUnJkjbEW138ssCmBEyIBeR7bonH0rLjebkft0k3gi-RQmJijFQVUD_48GdlNF-H1KxMXEdwKYkedFeBpWzXrty9pfz6rtB-fD392_nC6_RwggDRMAAANoAL7RYGxqXIY7KRKn8zOcU1FBQuQ5QpBUJttDXbo24k7PqxKOQ5KqnurcYE6WF5ED7r7cauNJ0BIkLVS_T5y-RJ7FdcBmEhpoLyVUfONvRTh4zQ9HSS6A1rRxWF0b0Qy4-3SQ69wLgCqYns4U0Iz-087RORG6J4Hee4ASFEqt7GQd6XHxlIeegCNgiXaad72T5AJS6U5Tw9ylXMERJ3Y7hxyA37yGxxFgmJ6kX5noxZkPae5TGp_6KjcFnNRkysTfWm7E4VHlywsfaAD6iXXB_WSzRZr9NPpr9E11QU1Nbuz3TYJXCdIx9Cd9z2Kr40cbbx2HopRmNIFcvAJeM7S55SQIjC9xFR2gbBJZU4jTNrh2EQBZvss8FJNHuNg7iQA_uStxBUYAgEU1v-jKwzUlaI-zZMOGHNqdnEkmFg3V7u_f7GIbxWTs-hzMbLtpfHD3Q4CChcjhLj5fmNEDwyRmoSNnVmnbBLkrIYMVWW1D5eYaTHB5z9C3r7vj7pNmGU-TdvbvpAKvHTlvAlS91a-9p5SJV9AneJNdSnldHg-UFSeNCUZwfYzO_IyjPLEtIBAjQRw6gb9gYjqYls2W5Cro7YaKgtKp7R9L2i6Vua7lHE87qQkEWvaRrNBplby1nVvyuaSTfR__tzdh0msCUb1YXOUJ1-ORzrbqTn-OeA1FZw01x6mL26vEelT1slIBgVwtrlxhC8IcCLyOr-qZTnB239bRNPYEWvL8862PjsrwSyDwuS-JHpBVSq5Ya-aPAm_puGr9K7P-OAv5o4QX-o2sMEODY3wf5i1qV6eOQrg81x2vPmj3mLCzBa07lEjI3UFett2lWIPiAwjEuRqE2RJLqmLFQG1cyda1eWMjoEL8wVgW__JIJNB__Ms_o7AGpXfKFD5XsjM0XOzix90QBXa1GXkOCJIuKJ_X98u6sR8-K_zc594cCRX0cWd12wBWwsfyuDpuisVssn64anpZo5nFYVFQLOc5KXSl-188gi-WPnzUif2YkNcvCDd-JwfqB7--e4y7r8w9TCRkiaSgsFEXM1kF1f7aGFjWRNfGksAXfPj-L0XBoJLAbgrwbBGf7uDDmvY81L6pHz6am-6ekfCOT7MOYKElo03MaNpJ7EwJpLh0eqUYqcjYvsP80ZuZZmgA9NTCRo4thXsEkuZBEtUidWYpplEt1rQvtv005p2mCLoBq5gItTIADS15U2U8MhKc6lsbh0yVshMp7uS3rjUVx18RpHB15FTSip80kvZaWtFr9ZUYYGPfuoycjBaBlPBwOfTGNeZwj1Qs0W2wXSTyP_Ae0COu0_vBFIzbgs380jeO-Z3nwYiLi3asrnF8ruh_0LHQpoBHgv-SZ49dq1pMlsvH_Z02mCgEMfe5vmz8kG-AC_lLp8phiW1yMG7LLi8TGAh04OtZhkza6T1RAPKmx7TY9HL1vIKOhz18v_IrtD8fPUn70ZZRxXXhOcht9dzi71bA06AmM_u_RJKmWd3N29zct-a_tDXqnJfMJsjm4YST_Bx22L8a2U51MMre8U0iwGJH4rnkRC0K9KTBYtcYf-UvAKWUDETcQdRiLUqKiJn4Y6PtwSwrKz7uv3bGy2czeddkYjlUDACiIeCS8dQZQ1HyaOrMmOWwY64Asv5Ww0fa_v39wIiQ6y3McEWhZpgEYbL85V7X5Mz9xW61E8vqGXNXycFj0AbCZSzLCq6ObcHu3vfrcNbqXf9032pE8MioAHC-frdZreyCJBz9FARDB0kMrW4umr5F4AX3XY3q5Zqo4E-dYIylI4CqXfW_v9pAkuihLJagi00_GcjsH5K81NIoaqXN70GOCC1XtgfRKjjzl81mDcX_hcbkyiiMuP4tU18ht7Td5u3hslMtyz6nxcApSde7FO1RbIT32OuyvRLt9QQn5Q-S3FsvigROHPArwLYeopDwnqlqrMY3pnnN7juzt8HlO4Mng-rOD8YNa8y8kWvpwSi4MEZJQS51wQvdZwidZbIWUXnJ4TbJ6WBPf_pXc0bPRxMvAiOhDxaEih-skg.EZP5ZCcx-7cFTBr-eZrSkUg7WGkteClhq0W620AywpQ\",\"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\":1776142701112},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjE0NDIwMCwiaWF0IjoxNzc2MTQwOTAwLCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiJmM2U5M2Y5OS1hOWJiLTRkYmYtOWRlMi1mZWVkYWJmMDA1OWUiLCJhdF9oYXNoIjoiSXZ3Z1JuQWN6bmhmUFlVYWVjQ2pzUSJ9.OnBsWI1skzWBkONRAGjAgSX2-UEqPoANG_Z8jMs4VHakd38Hgim5NPO39Np3yX2hWNCyiMEsLs3KoMyNcmuvmqNcz36nSMrbspnPbKetnsPwhLcl1y2VzARSJz7AwuEUCKcDFi6fQVRz4WP0yUXxyCEwzWBtRRfU0RpEoDvvXn_gEW5I6Rpt57Pxr6dwjDKXenAlZVepg8W453mmj8Dgbr-MFGb03UewrWDY63kjJZuNqfhuMQH5v-g3oPfh5xX_MQaJPxYbiGGNw2mC2-QU5ZGKSk2ScfrUgVtDtNGKxFGzQeiaFe-EyNTa2qO_6JgxhfnOYyItC-ujQOUNAQ1qzA\"},\"dpopKeyThumbprint\":\"E7rvIabCjI6h8Vr_n2eT6S3VenBwE1SyA3bp19NMsIs\",\"issuedAtEpochMs\":1776140901113,\"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\":1776140899000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" + ], + [ + "stellaops:wasEverAuth", + "true" + ] + ] + }, + "events": { + "consoleErrors": [], + "requestFailures": [], + "responseErrors": [] + }, + "statePath": "C:\\dev\\New folder\\git.stella-ops.org\\src\\Web\\StellaOps.Web\\output\\playwright\\live-setup-wizard-state-truth-check.state.json" +} diff --git a/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-state-truth-check.json b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-state-truth-check.json new file mode 100644 index 000000000..57fb697fa --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-state-truth-check.json @@ -0,0 +1,855 @@ +{ + "generatedAtUtc": "2026-04-14T04:28:38.939Z", + "failedActionCount": 0, + "runtimeIssueCount": 0, + "results": [ + { + "action": "welcome-route", + "ok": true, + "snapshot": { + "label": "welcome", + "url": "https://stella-ops.local/setup-wizard/wizard?mode=reconfigure", + "title": "Wizard - StellaOps", + "heading": "Welcome to Stella Ops", + "alerts": [], + "visibleButtons": [ + "Start Setup" + ] + }, + "session": { + "status": 200, + "ok": true, + "sessionId": "setup-installation-20260414042825", + "currentStepId": "database", + "sessionStatus": "in_progress", + "steps": [ + { + "stepId": "database", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + }, + { + "stepId": "cache", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + }, + { + "stepId": "migrations", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + }, + { + "stepId": "admin", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + }, + { + "stepId": "crypto", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + } + ], + "raw": { + "status": 200, + "ok": true, + "body": { + "session": { + "sessionId": "setup-installation-20260414042825", + "scopeKey": "installation", + "tenantId": "installation", + "status": "InProgress", + "currentStepId": "Database", + "definitionVersion": "2026-04-control-plane-v1", + "steps": [ + { + "stepId": "Database", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Valkey", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Migrations", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Admin", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Crypto", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + } + ], + "draftValues": {}, + "createdAtUtc": "2026-04-14T04:28:25Z", + "updatedAtUtc": "2026-04-14T04:28:25Z", + "completedAtUtc": null, + "createdBy": "57e23364287447d6aed31ca3f6115ee8", + "updatedBy": "57e23364287447d6aed31ca3f6115ee8", + "dataAsOfUtc": "2026-04-14T04:28:25Z" + } + }, + "bodyText": "{\"session\":{\"sessionId\":\"setup-installation-20260414042825\",\"scopeKey\":\"installation\",\"tenantId\":\"installation\",\"status\":\"InProgress\",\"currentStepId\":\"Database\",\"definitionVersion\":\"2026-04-control-plane-v1\",\"steps\":[{\"stepId\":\"Database\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Valkey\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Migrations\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Admin\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Crypto\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null}],\"draftValues\":{},\"createdAtUtc\":\"2026-04-14T04:28:25Z\",\"updatedAtUtc\":\"2026-04-14T04:28:25Z\",\"completedAtUtc\":null,\"createdBy\":\"57e23364287447d6aed31ca3f6115ee8\",\"updatedBy\":\"57e23364287447d6aed31ca3f6115ee8\",\"dataAsOfUtc\":\"2026-04-14T04:28:25Z\"}}" + } + }, + "forcedSession": { + "status": 201, + "ok": true, + "body": { + "session": { + "sessionId": "setup-installation-20260414042825", + "scopeKey": "installation", + "tenantId": "installation", + "status": "InProgress", + "currentStepId": "Database", + "definitionVersion": "2026-04-control-plane-v1", + "steps": [ + { + "stepId": "Database", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Valkey", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Migrations", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Admin", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Crypto", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + } + ], + "draftValues": {}, + "createdAtUtc": "2026-04-14T04:28:25Z", + "updatedAtUtc": "2026-04-14T04:28:25Z", + "completedAtUtc": null, + "createdBy": "57e23364287447d6aed31ca3f6115ee8", + "updatedBy": "57e23364287447d6aed31ca3f6115ee8", + "dataAsOfUtc": "2026-04-14T04:28:25Z" + } + }, + "bodyText": "{\"session\":{\"sessionId\":\"setup-installation-20260414042825\",\"scopeKey\":\"installation\",\"tenantId\":\"installation\",\"status\":\"InProgress\",\"currentStepId\":\"Database\",\"definitionVersion\":\"2026-04-control-plane-v1\",\"steps\":[{\"stepId\":\"Database\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Valkey\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Migrations\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Admin\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Crypto\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null}],\"draftValues\":{},\"createdAtUtc\":\"2026-04-14T04:28:25Z\",\"updatedAtUtc\":\"2026-04-14T04:28:25Z\",\"completedAtUtc\":null,\"createdBy\":\"57e23364287447d6aed31ca3f6115ee8\",\"updatedBy\":\"57e23364287447d6aed31ca3f6115ee8\",\"dataAsOfUtc\":\"2026-04-14T04:28:25Z\"}}" + } + }, + { + "action": "start-setup", + "ok": true, + "snapshot": { + "label": "database-step", + "url": "https://stella-ops.local/setup-wizard/wizard?mode=reconfigure", + "title": "Wizard - StellaOps", + "heading": "Reconfigure", + "alerts": [], + "visibleButtons": [ + "Validate Connection", + "Apply and ContinueValkey/Redis Cache" + ] + }, + "session": { + "status": 200, + "ok": true, + "sessionId": "setup-installation-20260414042825", + "currentStepId": "database", + "sessionStatus": "in_progress", + "steps": [ + { + "stepId": "database", + "status": "pending", + "lastProbeSucceeded": true, + "errorMessage": null + }, + { + "stepId": "cache", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + }, + { + "stepId": "migrations", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + }, + { + "stepId": "admin", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + }, + { + "stepId": "crypto", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + } + ], + "raw": { + "status": 200, + "ok": true, + "body": { + "session": { + "sessionId": "setup-installation-20260414042825", + "scopeKey": "installation", + "tenantId": "installation", + "status": "InProgress", + "currentStepId": "Database", + "definitionVersion": "2026-04-control-plane-v1", + "steps": [ + { + "stepId": "Database", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": "2026-04-14T04:28:29Z", + "lastProbeSucceeded": true, + "checkResults": [ + { + "checkId": "check.database.connectivity", + "status": "Pass", + "message": "PostgreSQL connection established.", + "suggestedFix": null + }, + { + "checkId": "check.database.version", + "status": "Pass", + "message": "Server version 18.1.", + "suggestedFix": null + } + ], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Valkey", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Migrations", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Admin", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Crypto", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + } + ], + "draftValues": {}, + "createdAtUtc": "2026-04-14T04:28:25Z", + "updatedAtUtc": "2026-04-14T04:28:29Z", + "completedAtUtc": null, + "createdBy": "57e23364287447d6aed31ca3f6115ee8", + "updatedBy": "57e23364287447d6aed31ca3f6115ee8", + "dataAsOfUtc": "2026-04-14T04:28:29Z" + } + }, + "bodyText": "{\"session\":{\"sessionId\":\"setup-installation-20260414042825\",\"scopeKey\":\"installation\",\"tenantId\":\"installation\",\"status\":\"InProgress\",\"currentStepId\":\"Database\",\"definitionVersion\":\"2026-04-control-plane-v1\",\"steps\":[{\"stepId\":\"Database\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":\"2026-04-14T04:28:29Z\",\"lastProbeSucceeded\":true,\"checkResults\":[{\"checkId\":\"check.database.connectivity\",\"status\":\"Pass\",\"message\":\"PostgreSQL connection established.\",\"suggestedFix\":null},{\"checkId\":\"check.database.version\",\"status\":\"Pass\",\"message\":\"Server version 18.1.\",\"suggestedFix\":null}],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Valkey\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Migrations\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Admin\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Crypto\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null}],\"draftValues\":{},\"createdAtUtc\":\"2026-04-14T04:28:25Z\",\"updatedAtUtc\":\"2026-04-14T04:28:29Z\",\"completedAtUtc\":null,\"createdBy\":\"57e23364287447d6aed31ca3f6115ee8\",\"updatedBy\":\"57e23364287447d6aed31ca3f6115ee8\",\"dataAsOfUtc\":\"2026-04-14T04:28:29Z\"}}" + } + } + }, + { + "action": "probe-does-not-complete-step", + "ok": true, + "snapshot": { + "label": "after-probe", + "url": "https://stella-ops.local/setup-wizard/wizard?mode=reconfigure", + "title": "Wizard - StellaOps", + "heading": "Reconfigure", + "alerts": [], + "visibleButtons": [ + "Validate Connection", + "Apply and ContinueValkey/Redis Cache" + ] + }, + "session": { + "status": 200, + "ok": true, + "sessionId": "setup-installation-20260414042825", + "currentStepId": "database", + "sessionStatus": "in_progress", + "steps": [ + { + "stepId": "database", + "status": "pending", + "lastProbeSucceeded": true, + "errorMessage": null + }, + { + "stepId": "cache", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + }, + { + "stepId": "migrations", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + }, + { + "stepId": "admin", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + }, + { + "stepId": "crypto", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + } + ], + "raw": { + "status": 200, + "ok": true, + "body": { + "session": { + "sessionId": "setup-installation-20260414042825", + "scopeKey": "installation", + "tenantId": "installation", + "status": "InProgress", + "currentStepId": "Database", + "definitionVersion": "2026-04-control-plane-v1", + "steps": [ + { + "stepId": "Database", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": "2026-04-14T04:28:30Z", + "lastProbeSucceeded": true, + "checkResults": [ + { + "checkId": "check.database.connectivity", + "status": "Pass", + "message": "PostgreSQL connection established.", + "suggestedFix": null + }, + { + "checkId": "check.database.version", + "status": "Pass", + "message": "Server version 18.1.", + "suggestedFix": null + } + ], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Valkey", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Migrations", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Admin", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Crypto", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + } + ], + "draftValues": {}, + "createdAtUtc": "2026-04-14T04:28:25Z", + "updatedAtUtc": "2026-04-14T04:28:30Z", + "completedAtUtc": null, + "createdBy": "57e23364287447d6aed31ca3f6115ee8", + "updatedBy": "57e23364287447d6aed31ca3f6115ee8", + "dataAsOfUtc": "2026-04-14T04:28:30Z" + } + }, + "bodyText": "{\"session\":{\"sessionId\":\"setup-installation-20260414042825\",\"scopeKey\":\"installation\",\"tenantId\":\"installation\",\"status\":\"InProgress\",\"currentStepId\":\"Database\",\"definitionVersion\":\"2026-04-control-plane-v1\",\"steps\":[{\"stepId\":\"Database\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":\"2026-04-14T04:28:30Z\",\"lastProbeSucceeded\":true,\"checkResults\":[{\"checkId\":\"check.database.connectivity\",\"status\":\"Pass\",\"message\":\"PostgreSQL connection established.\",\"suggestedFix\":null},{\"checkId\":\"check.database.version\",\"status\":\"Pass\",\"message\":\"Server version 18.1.\",\"suggestedFix\":null}],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Valkey\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Migrations\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Admin\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Crypto\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null}],\"draftValues\":{},\"createdAtUtc\":\"2026-04-14T04:28:25Z\",\"updatedAtUtc\":\"2026-04-14T04:28:30Z\",\"completedAtUtc\":null,\"createdBy\":\"57e23364287447d6aed31ca3f6115ee8\",\"updatedBy\":\"57e23364287447d6aed31ca3f6115ee8\",\"dataAsOfUtc\":\"2026-04-14T04:28:30Z\"}}" + } + } + }, + { + "action": "apply-advances-backend-state", + "ok": true, + "snapshot": { + "label": "after-apply", + "url": "https://stella-ops.local/setup-wizard/wizard?mode=reconfigure", + "title": "Wizard - StellaOps", + "heading": "Reconfigure", + "alerts": [ + "PostgreSQL Database configured successfullyRun Doctor re-check to verify Run Re-check" + ], + "visibleButtons": [ + "PreviousPostgreSQL Database", + "Apply and ContinueDatabase Migrations", + "Run Re-check" + ] + }, + "session": { + "status": 200, + "ok": true, + "sessionId": "setup-installation-20260414042825", + "currentStepId": "cache", + "sessionStatus": "in_progress", + "steps": [ + { + "stepId": "database", + "status": "completed", + "lastProbeSucceeded": true, + "errorMessage": null + }, + { + "stepId": "cache", + "status": "pending", + "lastProbeSucceeded": true, + "errorMessage": null + }, + { + "stepId": "migrations", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + }, + { + "stepId": "admin", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + }, + { + "stepId": "crypto", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + } + ], + "raw": { + "status": 200, + "ok": true, + "body": { + "session": { + "sessionId": "setup-installation-20260414042825", + "scopeKey": "installation", + "tenantId": "installation", + "status": "InProgress", + "currentStepId": "Valkey", + "definitionVersion": "2026-04-control-plane-v1", + "steps": [ + { + "stepId": "Database", + "status": "Passed", + "completedAtUtc": "2026-04-14T04:28:33Z", + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": "2026-04-14T04:28:33Z", + "lastProbeSucceeded": true, + "checkResults": [ + { + "checkId": "check.database.connectivity", + "status": "Pass", + "message": "PostgreSQL connection established.", + "suggestedFix": null + }, + { + "checkId": "check.database.version", + "status": "Pass", + "message": "Server version 18.1.", + "suggestedFix": null + } + ], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Valkey", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": "2026-04-14T04:28:33Z", + "lastProbeSucceeded": true, + "checkResults": [ + { + "checkId": "check.services.valkey.connectivity", + "status": "Pass", + "message": "Connected to cache.stella-ops.local:6379.", + "suggestedFix": null + } + ], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Migrations", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Admin", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Crypto", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + } + ], + "draftValues": {}, + "createdAtUtc": "2026-04-14T04:28:25Z", + "updatedAtUtc": "2026-04-14T04:28:33Z", + "completedAtUtc": null, + "createdBy": "57e23364287447d6aed31ca3f6115ee8", + "updatedBy": "57e23364287447d6aed31ca3f6115ee8", + "dataAsOfUtc": "2026-04-14T04:28:33Z" + } + }, + "bodyText": "{\"session\":{\"sessionId\":\"setup-installation-20260414042825\",\"scopeKey\":\"installation\",\"tenantId\":\"installation\",\"status\":\"InProgress\",\"currentStepId\":\"Valkey\",\"definitionVersion\":\"2026-04-control-plane-v1\",\"steps\":[{\"stepId\":\"Database\",\"status\":\"Passed\",\"completedAtUtc\":\"2026-04-14T04:28:33Z\",\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":\"2026-04-14T04:28:33Z\",\"lastProbeSucceeded\":true,\"checkResults\":[{\"checkId\":\"check.database.connectivity\",\"status\":\"Pass\",\"message\":\"PostgreSQL connection established.\",\"suggestedFix\":null},{\"checkId\":\"check.database.version\",\"status\":\"Pass\",\"message\":\"Server version 18.1.\",\"suggestedFix\":null}],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Valkey\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":\"2026-04-14T04:28:33Z\",\"lastProbeSucceeded\":true,\"checkResults\":[{\"checkId\":\"check.services.valkey.connectivity\",\"status\":\"Pass\",\"message\":\"Connected to cache.stella-ops.local:6379.\",\"suggestedFix\":null}],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Migrations\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Admin\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Crypto\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null}],\"draftValues\":{},\"createdAtUtc\":\"2026-04-14T04:28:25Z\",\"updatedAtUtc\":\"2026-04-14T04:28:33Z\",\"completedAtUtc\":null,\"createdBy\":\"57e23364287447d6aed31ca3f6115ee8\",\"updatedBy\":\"57e23364287447d6aed31ca3f6115ee8\",\"dataAsOfUtc\":\"2026-04-14T04:28:33Z\"}}" + } + } + }, + { + "action": "reload-preserves-session-state", + "ok": true, + "snapshot": { + "label": "after-reload", + "url": "https://stella-ops.local/setup-wizard/wizard?mode=reconfigure", + "title": "Wizard - StellaOps", + "heading": "Reconfigure", + "alerts": [], + "visibleButtons": [ + "PreviousPostgreSQL Database", + "Apply and ContinueDatabase Migrations" + ] + }, + "session": { + "status": 200, + "ok": true, + "sessionId": "setup-installation-20260414042825", + "currentStepId": "cache", + "sessionStatus": "in_progress", + "steps": [ + { + "stepId": "database", + "status": "completed", + "lastProbeSucceeded": true, + "errorMessage": null + }, + { + "stepId": "cache", + "status": "pending", + "lastProbeSucceeded": true, + "errorMessage": null + }, + { + "stepId": "migrations", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + }, + { + "stepId": "admin", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + }, + { + "stepId": "crypto", + "status": "pending", + "lastProbeSucceeded": null, + "errorMessage": null + } + ], + "raw": { + "status": 200, + "ok": true, + "body": { + "session": { + "sessionId": "setup-installation-20260414042825", + "scopeKey": "installation", + "tenantId": "installation", + "status": "InProgress", + "currentStepId": "Valkey", + "definitionVersion": "2026-04-control-plane-v1", + "steps": [ + { + "stepId": "Database", + "status": "Passed", + "completedAtUtc": "2026-04-14T04:28:33Z", + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": "2026-04-14T04:28:33Z", + "lastProbeSucceeded": true, + "checkResults": [ + { + "checkId": "check.database.connectivity", + "status": "Pass", + "message": "PostgreSQL connection established.", + "suggestedFix": null + }, + { + "checkId": "check.database.version", + "status": "Pass", + "message": "Server version 18.1.", + "suggestedFix": null + } + ], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Valkey", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": "2026-04-14T04:28:35Z", + "lastProbeSucceeded": true, + "checkResults": [ + { + "checkId": "check.services.valkey.connectivity", + "status": "Pass", + "message": "Connected to cache.stella-ops.local:6379.", + "suggestedFix": null + } + ], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Migrations", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Admin", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + }, + { + "stepId": "Crypto", + "status": "Pending", + "completedAtUtc": null, + "skippedAtUtc": null, + "skippedReason": null, + "lastProbedAtUtc": null, + "lastProbeSucceeded": null, + "checkResults": [], + "appliedConfig": {}, + "errorMessage": null + } + ], + "draftValues": {}, + "createdAtUtc": "2026-04-14T04:28:25Z", + "updatedAtUtc": "2026-04-14T04:28:39Z", + "completedAtUtc": null, + "createdBy": "57e23364287447d6aed31ca3f6115ee8", + "updatedBy": "57e23364287447d6aed31ca3f6115ee8", + "dataAsOfUtc": "2026-04-14T04:28:39Z" + } + }, + "bodyText": "{\"session\":{\"sessionId\":\"setup-installation-20260414042825\",\"scopeKey\":\"installation\",\"tenantId\":\"installation\",\"status\":\"InProgress\",\"currentStepId\":\"Valkey\",\"definitionVersion\":\"2026-04-control-plane-v1\",\"steps\":[{\"stepId\":\"Database\",\"status\":\"Passed\",\"completedAtUtc\":\"2026-04-14T04:28:33Z\",\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":\"2026-04-14T04:28:33Z\",\"lastProbeSucceeded\":true,\"checkResults\":[{\"checkId\":\"check.database.connectivity\",\"status\":\"Pass\",\"message\":\"PostgreSQL connection established.\",\"suggestedFix\":null},{\"checkId\":\"check.database.version\",\"status\":\"Pass\",\"message\":\"Server version 18.1.\",\"suggestedFix\":null}],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Valkey\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":\"2026-04-14T04:28:35Z\",\"lastProbeSucceeded\":true,\"checkResults\":[{\"checkId\":\"check.services.valkey.connectivity\",\"status\":\"Pass\",\"message\":\"Connected to cache.stella-ops.local:6379.\",\"suggestedFix\":null}],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Migrations\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Admin\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null},{\"stepId\":\"Crypto\",\"status\":\"Pending\",\"completedAtUtc\":null,\"skippedAtUtc\":null,\"skippedReason\":null,\"lastProbedAtUtc\":null,\"lastProbeSucceeded\":null,\"checkResults\":[],\"appliedConfig\":{},\"errorMessage\":null}],\"draftValues\":{},\"createdAtUtc\":\"2026-04-14T04:28:25Z\",\"updatedAtUtc\":\"2026-04-14T04:28:39Z\",\"completedAtUtc\":null,\"createdBy\":\"57e23364287447d6aed31ca3f6115ee8\",\"updatedBy\":\"57e23364287447d6aed31ca3f6115ee8\",\"dataAsOfUtc\":\"2026-04-14T04:28:39Z\"}}" + } + } + } + ], + "runtime": { + "consoleErrors": [], + "pageErrors": [], + "requestFailures": [], + "responseErrors": [] + } +} diff --git a/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-state-truth-check.state.json b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-state-truth-check.state.json new file mode 100644 index 000000000..cafbe8594 --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-state-truth-check.state.json @@ -0,0 +1,38 @@ +{ + "cookies": [], + "origins": [ + { + "origin": "https://stella-ops.local", + "localStorage": [ + { + "name": "stellaops.auth.session.full", + "value": "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjE0MjcwMCwiaWF0IjoxNzc2MTQwOTAwLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiN2IxMmNlMjUtNjI1YS00NDNjLTgxNzMtMDE1Njk5ODJmZjY1Iiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxNDA4OTksIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.YQU_wwjA_LpTBu5csRT_TBGWlahpbsTxz10R1RVD0BcA1UnorvY8zHdgA3AOFqf3_CUix_pD4XzzbWaA_PFnQ92uFEayR5V6vnZX_Mi3KKgdXuzItQPUKw21b0jA0WAMI1cOguwthAWGt_Phx2FdjN9g6JzlLbN18WzXSIq6hGZ2OtZUXITC7VFSfw1Sv9WNwergzJ-YhMr-S5AULZZcoPNX8Lv5X_A3Z6Z_qgnXwR2Or9dLEcVi9l0o-m7n74HJFTb34KhkRd2JzEFTbRdLdgc-yyEplx_GP9vKVdB0edflWQRbludVgHQQGt2BrQkjYx2Wllgly0DvQuBq5UJvxA\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.kRqSP9JfPSQcJV_XOHhtS_4UOa_M0JaDeYeZv-HZ-4lnMqQkWZnoqCHVv6AnuxYAmFrBkRsq_GN12eAPTmqsfbxshn7wKV6yw8qlWMtOJAy5W_khjN4GdQCpH_sN4FnIFTewI3VN9YPm9HsY9PRwJFs0hb40ctH7L1GCTiUteTD1EgnTjnZx6jjnBSozIxAN66oG0o1NIPFXOdRyL6086DsDUMzHowm4-Eo4IBkGnHi1nKE2wT75NQCh08ergofZEkfDGp-RFHdVj9Y0j6WByCUCoIHRFg5ip0z8NzDYkktNIKMR450DCwDFf92gXWbQnWaPRrnRHXXMksHZi3nusQ.2kz62Zrx8_7wABZ7fIHHQQ.Gf4AnTZHwvYeUylN9OR0uzR09A5YLSUegAchtGGMd7PRlW-L7O3-lUJv3tS14fEjcXdxPP7PMXKBoQh0n76l8KsWKhT1fGwA9lhAcTeOBq5YfUKViea5hHFgDh1X8D6ncvySn8ARa18fQmbbyqW_hoqxr27w4ObFBVCgsvyon904EZxWy1G9HhBFwVOYJzWlTBKhs0wq3RX_A6tHWVRPC293R1cP8U5uhH8yd4oK2_LN1n-GMlGiY8nAQc5luNHsc7QW7BuPyEQGzhgFlsbi7avC9CEZhMlRZe9k2HDVAFxjAscXGy5c0KU298_pUjL-9v3T7tyHwP1SumdvDK510xfuKITyj3s54R_MEZKcyupr5WoAwc7Iyt3ViwqgHTDZKyUuWSQR79XFsUH7QmCHuUOlRPuS0pSaClu2RFNnKAWOaIT4_4iTKF33AyRZgByQyGlDyI16tWJ92f3l2QVodZFzq2SmwW4AHFZP3Bu2V04_k1acsltk5_jZBlY2MSUkWLWIp9yS4hxuKw3b9fstbOSrQzC1NJu2d8sK_WgTpEoA9qGopms_CObuBDv-BI7949rr3V3i6YAmxXybqKJJiCvVPe9X3tUlsBLBxZPbRCTcFimnPpHG6-u-LN5oH_Rsaczd-Z6rYhnruufPOWjpSUmuJdyeHxO4DS7pRl0qGb9mglx5EMOV0CVJhiFYqSdP13cpAQ2VFsu5Am4RxvBX1paEfGrGRYwbkiVGIb5i51UmF741YvQ1BGBWS53f-B-L3HH1b4i_sfVdjItQ0fbSj2KQdcnXW-lCzUuKp56MMxLyyfGzJ9hAua-uMyZtnf8JvRBPcx4cXsKWHgfm4KpuPW6ko8OCKHV547myhLQMlUJwhkMlx9M1uWvGmZn3gyej2vY6Vd9VyyD5VjsSbkt6RafulHoRI0WB3KW_WRLKdRbK-HVpy87I6JDYn9DHD5e4GLIwUU0j6qS_xlPbdDEP7DFQ37fGMoV1KScqKDNyfGmpdJv6SQls_MFidiITox2au0PO4pwka9iA99bR3eAB1Oas2XzFRqky4wHIpwFMHTuzM9kUNk7tT0OMwZXLNZPqBj7r8jlXQAIDBl6V-DoW2qtSlPj6ssfXnPQ8N0MQWinKfEaUbPrYR9Ii9Q8f9-J_ezU-i0P1p2kEpKPdd-2_ZLM4gGBja1DGqtUhZOU7WPVXuydRgNG_DZBwzIoTNnIRZ8ahBYfDKk5kdzRxrFeXuGSVH5-XoU0ITpy2f8pg3l3Vll5QpWDh6peSqw4ZfrAbs-xCpNByGILmV8A6q37aQA0ouS66l_YkJuIkMlxkfHXOGGjX6vfS_Yu0EmUrCVBn4W_1B-M4nTf4gKTnomP8ip7QF4IaMqUMhbKMuYM6vzp3CjsnXmofi4_VB6l3-czFT2aatOY2QQ4ydRaPLn63i7FxHe8ZiMKevSzcSu2pZ5GoHp-INmujolvk60smAJdnm3MEBLJnDejhLON2_CBVOD22CMmvVRiUw12hJ7xiCIQambE7XlodWRXxHZq-YNP8SaGDXVtzjfcwZqLwc5D2E8P8m3OO8sUICBikRzevvdlv-7GJ0cxEDy5xDRvM9Sob1130fzjyCyijbxNquAAKBq5YYeKxYXvorvowjPMigjGFTlOYimuxVkHPkz3kqMnuy0h6aEwJlHZVqWfUamOpQGo6zmH6WZGSdAygVD9Os0hVB7NJvrRYLIdTFJK_0HLM0TTRx_-UN5zUME-1fnYv9Uuyh4EQ3gTbkL7zUb1RaE4p6SlnGpzEGUF8VKeVVQvK3PhXYVlrLn3j8caBBj0txpbHMaYXEpW_PgnihefzsSOJACb3ER9-e20skCPxeahOlL_f5YxbKDct_TxRTHNwvrVbgNQW6iAdsZVaAltsTqBCiHjfvE86H2-PcoK2n66oTR3FMPVAyepUHZnH-JJy2L52d99_eZDnDSJu4tUWyOK2Ez3YWuFSsgpYBCiBApSvdBiIxFiiygSY5kH88Dn2aVGua8MvnhzXHKfeMvrYR6C-CHOMA-GEpW4EU7KdwPAtxW1_vHY5-2o9RoEQ-NIdJ_xvRDytl5k59GLvLEeQUQiPgvjz-ix3Q0RyECKI_VoEDvz_lLzP-s2v0imwvFuV72E8eNLjPOzgu3LQ9wH9gz_5IwrVaauBmki_cw5Dhl69XIJ91gwbOk25kqlU2FzC2iJ3fKPVW5a-3-YX-q4l-AIl2iu2kHP4mm5MfCAD4ZuTtjJh_2ZSM6IoMRScc3EmfD6AlMjn1UIwG2cy8XvmbowwncZDXnuk66jmgWY3EdJEbIAPUSn6BoAQgGeIv6K-boLG2UVI9X2mgzWVpapxlB4GC0yB2LB0LdEtwOE-ScfJZtpICmsUUTO1RZSAk7qQCBr4-06kfQSneqaISsDQqe37quQev3UuYCZlv66Z2ufa1il-MSGy2Ei0mW5RrcjLCTolN6FRwxUUfMmg_4yNhFHgoRpuyATRkzIb4JQutSfoh49el3RtRm8-XRm_BqAUbzPB6SbF1ZY6rrpdFqf93fY2TPvHYIri4T7gGc_SJhb97XIAqTbm6OTs7xoQrLgjV_SkM7Vbdffhl9mP-Xj03UahxrcG2txUnJkjbEW138ssCmBEyIBeR7bonH0rLjebkft0k3gi-RQmJijFQVUD_48GdlNF-H1KxMXEdwKYkedFeBpWzXrty9pfz6rtB-fD392_nC6_RwggDRMAAANoAL7RYGxqXIY7KRKn8zOcU1FBQuQ5QpBUJttDXbo24k7PqxKOQ5KqnurcYE6WF5ED7r7cauNJ0BIkLVS_T5y-RJ7FdcBmEhpoLyVUfONvRTh4zQ9HSS6A1rRxWF0b0Qy4-3SQ69wLgCqYns4U0Iz-087RORG6J4Hee4ASFEqt7GQd6XHxlIeegCNgiXaad72T5AJS6U5Tw9ylXMERJ3Y7hxyA37yGxxFgmJ6kX5noxZkPae5TGp_6KjcFnNRkysTfWm7E4VHlywsfaAD6iXXB_WSzRZr9NPpr9E11QU1Nbuz3TYJXCdIx9Cd9z2Kr40cbbx2HopRmNIFcvAJeM7S55SQIjC9xFR2gbBJZU4jTNrh2EQBZvss8FJNHuNg7iQA_uStxBUYAgEU1v-jKwzUlaI-zZMOGHNqdnEkmFg3V7u_f7GIbxWTs-hzMbLtpfHD3Q4CChcjhLj5fmNEDwyRmoSNnVmnbBLkrIYMVWW1D5eYaTHB5z9C3r7vj7pNmGU-TdvbvpAKvHTlvAlS91a-9p5SJV9AneJNdSnldHg-UFSeNCUZwfYzO_IyjPLEtIBAjQRw6gb9gYjqYls2W5Cro7YaKgtKp7R9L2i6Vua7lHE87qQkEWvaRrNBplby1nVvyuaSTfR__tzdh0msCUb1YXOUJ1-ORzrbqTn-OeA1FZw01x6mL26vEelT1slIBgVwtrlxhC8IcCLyOr-qZTnB239bRNPYEWvL8862PjsrwSyDwuS-JHpBVSq5Ya-aPAm_puGr9K7P-OAv5o4QX-o2sMEODY3wf5i1qV6eOQrg81x2vPmj3mLCzBa07lEjI3UFett2lWIPiAwjEuRqE2RJLqmLFQG1cyda1eWMjoEL8wVgW__JIJNB__Ms_o7AGpXfKFD5XsjM0XOzix90QBXa1GXkOCJIuKJ_X98u6sR8-K_zc594cCRX0cWd12wBWwsfyuDpuisVssn64anpZo5nFYVFQLOc5KXSl-188gi-WPnzUif2YkNcvCDd-JwfqB7--e4y7r8w9TCRkiaSgsFEXM1kF1f7aGFjWRNfGksAXfPj-L0XBoJLAbgrwbBGf7uDDmvY81L6pHz6am-6ekfCOT7MOYKElo03MaNpJ7EwJpLh0eqUYqcjYvsP80ZuZZmgA9NTCRo4thXsEkuZBEtUidWYpplEt1rQvtv005p2mCLoBq5gItTIADS15U2U8MhKc6lsbh0yVshMp7uS3rjUVx18RpHB15FTSip80kvZaWtFr9ZUYYGPfuoycjBaBlPBwOfTGNeZwj1Qs0W2wXSTyP_Ae0COu0_vBFIzbgs380jeO-Z3nwYiLi3asrnF8ruh_0LHQpoBHgv-SZ49dq1pMlsvH_Z02mCgEMfe5vmz8kG-AC_lLp8phiW1yMG7LLi8TGAh04OtZhkza6T1RAPKmx7TY9HL1vIKOhz18v_IrtD8fPUn70ZZRxXXhOcht9dzi71bA06AmM_u_RJKmWd3N29zct-a_tDXqnJfMJsjm4YST_Bx22L8a2U51MMre8U0iwGJH4rnkRC0K9KTBYtcYf-UvAKWUDETcQdRiLUqKiJn4Y6PtwSwrKz7uv3bGy2czeddkYjlUDACiIeCS8dQZQ1HyaOrMmOWwY64Asv5Ww0fa_v39wIiQ6y3McEWhZpgEYbL85V7X5Mz9xW61E8vqGXNXycFj0AbCZSzLCq6ObcHu3vfrcNbqXf9032pE8MioAHC-frdZreyCJBz9FARDB0kMrW4umr5F4AX3XY3q5Zqo4E-dYIylI4CqXfW_v9pAkuihLJagi00_GcjsH5K81NIoaqXN70GOCC1XtgfRKjjzl81mDcX_hcbkyiiMuP4tU18ht7Td5u3hslMtyz6nxcApSde7FO1RbIT32OuyvRLt9QQn5Q-S3FsvigROHPArwLYeopDwnqlqrMY3pnnN7juzt8HlO4Mng-rOD8YNa8y8kWvpwSi4MEZJQS51wQvdZwidZbIWUXnJ4TbJ6WBPf_pXc0bPRxMvAiOhDxaEih-skg.EZP5ZCcx-7cFTBr-eZrSkUg7WGkteClhq0W620AywpQ\",\"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\":1776142701112},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjE0NDIwMCwiaWF0IjoxNzc2MTQwOTAwLCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiJmM2U5M2Y5OS1hOWJiLTRkYmYtOWRlMi1mZWVkYWJmMDA1OWUiLCJhdF9oYXNoIjoiSXZ3Z1JuQWN6bmhmUFlVYWVjQ2pzUSJ9.OnBsWI1skzWBkONRAGjAgSX2-UEqPoANG_Z8jMs4VHakd38Hgim5NPO39Np3yX2hWNCyiMEsLs3KoMyNcmuvmqNcz36nSMrbspnPbKetnsPwhLcl1y2VzARSJz7AwuEUCKcDFi6fQVRz4WP0yUXxyCEwzWBtRRfU0RpEoDvvXn_gEW5I6Rpt57Pxr6dwjDKXenAlZVepg8W453mmj8Dgbr-MFGb03UewrWDY63kjJZuNqfhuMQH5v-g3oPfh5xX_MQaJPxYbiGGNw2mC2-QU5ZGKSk2ScfrUgVtDtNGKxFGzQeiaFe-EyNTa2qO_6JgxhfnOYyItC-ujQOUNAQ1qzA\"},\"dpopKeyThumbprint\":\"E7rvIabCjI6h8Vr_n2eT6S3VenBwE1SyA3bp19NMsIs\",\"issuedAtEpochMs\":1776140901113,\"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\":1776140899000,\"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}" + }, + { + "name": "stellaops.theme", + "value": "system" + }, + { + "name": "stellaops.auth.session.info", + "value": "{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"expiresAtEpochMs\":1776142701112,\"issuedAtEpochMs\":1776140901113,\"dpopKeyThumbprint\":\"E7rvIabCjI6h8Vr_n2eT6S3VenBwE1SyA3bp19NMsIs\",\"tenantId\":\"demo-prod\"}" + }, + { + "name": "stellaops.sidebar.preferences", + "value": "{\"sidebarCollapsed\":false,\"collapsedGroups\":[\"evidence\",\"setup-admin\"],\"collapsedSections\":[]}" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-tokens.auth.json b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-tokens.auth.json new file mode 100644 index 000000000..904dbd6bc --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-tokens.auth.json @@ -0,0 +1,85 @@ +{ + "authenticatedAtUtc": "2026-04-13T22:24:35.824Z", + "baseUrl": "https://stella-ops.local", + "finalUrl": "https://stella-ops.local/?tenant=demo-prod®ions=apac,eu-west,us-east,us-west", + "title": "Dashboard - StellaOps", + "cookies": [], + "storage": { + "localStorageEntries": [ + [ + "stellaops.auth.session.full", + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyMDg3MiwiaWF0IjoxNzc2MTE5MDcyLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiMzliN2M1ZmYtODRhYS00MmNiLWFhNjQtNmUyMGFiMWU3MGRmIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMTkwNzIsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.MHiRntRahfIwJMXhzh5xMpL46KM01jVwU7CPRkHHc_8PMgj8GtXAQX0DOWuWJ30Qgjbbu2mI7e4cUcWGC8Jj4XkNjEcns--l2rMkyhgG8CCu2vd5rUL-X7mbxGi-VzwNEp6lcaD1pi7SCWfPJuTmYMQs5xh2HXkMa3xMauzfzwDeuiFO_OTtrv_L-342-5PwYX8LS71a1ROVKKbuXHvzCcbNJa_7WtopNoIh9u8kSTRiPkizIeJkHwqBhC6bBg-Dxx6YE2Y-ax4TPdC8o5Alc3aGPi0RQboCDvy1FbIgwH1yYKJHBDXLlxU-cL0_ewsA91MYSStgdJ9h_9qpEKzswA\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.Fz-k6KlAa0wxHxePmM4jqkuuCDd72lICMquXMqTfI-Ru_npY05nYupTgxoqADorDdJEApvhc5HsrO89-gj55XVEaj38LjBdA0KnNhMlJcbc0CVCTtq0Bs0s7dBwn3znVnCA6aUmuCXrbb97s9kyBOhy2UBaa07jk7tHwnWzqV94wT2rLUSngM7-RqtpGWLVrQ1CBi1ge5qXW4aA9aec6YTZkJ4NFa4SagtrhFWlNOW5JuYytq_BN5m9CZsgZuuvXaKFTm00wY1LsPN0H9viFOPkDTt4fIQW3qGVIGuDR8jDaWdnNHfSJnAb_GAAhFnQmMd1I3NMPzyVusdxx6wO1Lw.KyOUCjObio0NfYglmlLoUg.Mm08l7mIFTibKFhfSyTcLMYUr4JpKV1L9Hc6hRa9yVZFzvXIxwfV3AXFBgIonjSUuV2RxZW7M36_DDdZExDR9EIWSV_4laoejCa5YqQtzZqH_NhIXGv5MtllgvuZ4i5OP6HmoIjD4DYkDaWOqVkdcc_5r7EtozIvPUNTeBptSRClHSrKV53oyV5EiIISLCuHjTRnvmb82QOZnc-oAbw45ost9cmCKcHylDjLyiX2DSLeatIlEhf47r-i7wj1MW0EjJB2Ur1oP51UpPMTVT1eZPKBAh5Ta8HEeARRsNSCeHRukip6rSDecUOgcWZsQDgHevy12eRPFGPu2eDuN7FOeSWZwX1NIWD7d0Hg70rWs__Q6G0Juf_Yys6HcsCWMoC4k8VyH3GbBRYHHu41qYrAdS8w_VJjaOMMSlGV4SGK12x5a2rAmTVgiK3AtCnoNCrUoCdQ4DQtKZCqxg5J-xQMD_nL7AbTEc-D8L7zURVH_2CE_7JTp9cAyL1PU98XvYkSd__nC9qURHnHKeVD34_euHoA9z6u1HRNYQxOeAlW19qreOMbAmf1XJTrcVEPHOMyJn5p5u4iwEZtYGpTRKv7g7UMBiEdd_S-idVumS8NLK0n9fdGF6qdKA7noA5PhkQ4hvWAOmEPJaQr6ipaE7qxdHN4-0dnkxT_KeCKBypjg9YbHRW9LKDR_eF7sMzWMcliZgO--T-p37nyUiRp6R2-sU3YuqEcsCD-4bDOXFY9xVzotPO-VWAx7VfIPSDixrmCNaZdEz87wbdFUJ5irEcdAXialv0L5kyagMzWkflI6yfpVzoe5PvAFad1R0WIdMISItAQlDZqFKWP6Myp7lbmiWey6OTRa0KcR2c4DrIPpSaXOb-KxpsJcq1I9RObAiYLgrZiMG2XlsUj6kMdQzr1Nh0c9pvlCBoVrLaIaIEIAD19pswtgg4lfYZlL1hxDVBCM-QAg0Edj5SJSyw-PM2YHRxhM9my0bvGlJA1PN79-S2RA6-mOhFteRFR_0QoM4Oxjba94kbs3ZjeRtqHN8iCu4sE4bNUj45pRO5R3-mGt5Jh5h6GSY4ZyoBGpH3CflN_8NVdkBGtHRtFP_6oEJFjY66twiSehs-fzVu3s1v5uH7q7SzJzmrh_eHT8cwREYFGsXcNr7C-xFxw1i7E8LnKghtPzZys7XMAJfq_qXQoRETkwFjmn-W8i_rp1biGZS9ifp9pNhLelzMLkzwT3REg8xoUqjdchUrtDgqB1f3OIWZ5XzXVSrX25AASwtoAuAo6aIRyxoBGpJAYO1dbQfoztFuvepMG_h8Grw7U1TNhr5WFhl3LEYxqb-qbtJx6cqneT3oSewDfALOCMqgITnNoGkALKANfoh-NUt2o7KYZzKHlymTzRuBbomClgxMOz3sJlg8w3JZCD-Yq7UEWZUurOE-YM541O4mL8eOPctOE7pBjVU9_tT7RQmDM2lbQX2_f1wbQZc2o9WV_f6TMScbjDcRH0jQ2S8B6Iy6mKcYMAauXIPphftt-AwuPATt-ecyps79rUOJHo_QZiA9VPE4LYuhtVUDDeQ92QMjNhz_095wK9sdtis_tGul1kh-B1B6Fi2N4I0cV3cXX5f1Gq0lQar3GHoOxbThgKJxRL0nR339QEipc084TRyG0ExWfXEZfus95fa-l0VC0xHdjN-we4TbGOm5jwEO7RZvUrBTbvcpXqUMycKJFnxXXp8XZRX4OSl92DxqsiAbyU9irqOCaXke3doPDbDUp2umgXmp2yhZU7EdeyPeE5YIDEL2mq7knQY5WaH9RwPQvzQT8VBcV75ScCtodPM_12yGpsu1P2qzsC3_OAzOK_Wv8sKWBuHuvhw06wgMdTiNJ9Qt4r5hyiH47usNtyrdbGUUTSHkpPfSzR7fMaVhH1koj1tqpM9bJixjBDhDGd-YgQFcPeW93aQvMoaSDKNeZSryWRXUwPaDpiolNulhTDVXFSqJM6pLa_yMw7zh1uJ6jt6Qhb2ime2P8LU1i56AD3k5dDZknVDfQYvSYRERNw3YP9pK7MYMQDkrlZ9DyR7Xx50L67z0JvvNHZ8j320IXWqhx4XpDeJnIKHc8qf5y0FOYKDnCAI5LQDro0UtYQ19kBoWxtLyweAlZ1OQU44gD8GFkQDfCuSeQKSSzEKLeUchRvyWaqsIidTIig1plq39O8nW1f3dt0escqp2smmO9UHh8nIaKO03jaW-vCb9lS8k8BlknxSWoj7174ibZKuJgFkbEe7w6UtoADn9kU9wlJ4yAKCW8MmIhCI3eR3Eu6T680qmNiIcSr3kZJBcP3FozXO5lsjmJfPmvTxwjwCpNrX-LOlp9Aw-mMiMpu-IXkTCVt8xxKwO0vdpXWup1HrGn1-5TpKXyx1cwjL-Nw25A4SW4eaTMVou-KHQwiez7XaAJmMwZluu9ChTmp46s7xFYIJapC5090BGMua2SVr1DnQWvFSqnutjL06XG8n_9CChEKbGi9QJYWrPdMeDQFnTndsdJM1CFguvrnxUm8WvZEjd3sIysugaJFepYFnrPtJktQ9Tn3JrgVBpVMmMc9G9WaXB4_eziq2F4nMQ8BPaDamBXZA_picqOmmynCtSlTz4UhYmoqIdSKRKgMcc0UI5vdDwdPEqvuaayXVb4DK86M2qLrfLnyDlp1K-U_iqtoMRce6_UqY_b2x7d-bovSl98eVn4yygamYi8OSYAgAzx0EpymXLy2SUCuo_qdBmsQiKs7U-5gUtJLN5q8aHq9zrulMidBlGAQP4C19I9k6A7CkbKzQerEr8J-2gzo81PA6YkkPwsFMQqcgn7668KH0SygTnMArz3D1Z9avrJGZQ0iSb9aDT0e4GtkWx00LTf4MX6xhSdvkveodgNwiz5Ti6-00Xicchc8yIatGWHktmEhKnxesZNdDM_dLvS4gEC6oo6puEc7M6Cx12xgt7-S-Rndrwk8E4DU2yDGW1FH9ZeDig8vGvqJxrTE0YcOjF9vk1h9jtUfPCEGSuKNG0f0qRl3V_zeRbdA9v0gwSY76o-gxez1tUJLuEHPgrvNor9zOosrzDX6WY92L2NIpnx63W9I81Hehj3ro9r8RrpsE0wBJ7QCUeLt1aI3tgxDsD_Fha8pmaQC9Q6v9qUFJ5-0_3BjEpKgrixJYTNWv1CzBt8THIfjh8H2rvknPvsEf3V_XBLJUQ3C04oNBb2k1UMBp92nYpOyA4ulvIvepf42k8V2wN11BF3v4bdIJakqAEU086ijVeEbVzjC365W53ZqcoOTHB_xsJT4aH4Oiw54J3ZcHVGoANQwazJW3KUJ5_MMVutFYXAsBpyV4l-SAbPF55XsVN7CCdK6LRIJ4Pz7OUhX66hIS5kZt_arYO_rHZSr4AyMQU-Pw4Tz-nEUAYLyYzDzr2MdhEFj-ED3NH4tXkpPYwuv81uvtEIZeIIGhbQ23BRKBtq4AGygzNiJf6ZRWXpXqNWYd8hDbIycTYzUaWVxEXM0W5f-v6sen9V-blAsGjHnH2g9_lEmEu-H1WdMv-frMQt8LYirg_7hir-pbLEwjb5j8uXp1orIJdvvdQwcaOs6jh1NOwjzYYHKhIoXWH2l8pQPwfctAMs4u8OmaaYRJGzG7-B-uAVcuw0a__yXb8YqCw3VO7N14Ir20IucluJ4vq_mHJDVVz3YM6dJtBWN1CLDnv6mGzCAh_7GpKi9XOCOY_sUDc3gr9aodgdwNKKrPK7m6JSD-6FgpLQz_sLzfi31sot-NQCuD5kgZW30X4iyeqI6r290HNaHA7Q-RKXfb-OVWtkr0Btj3qb9NuJJYiOtjam3x3tZHQta6o_7wchHJINJKckfJtnxVX3TOFzHebmkCcjaI23fEtg7dvTahcc7LXBhS1ls2dy5JPjTc9bjTrptXYlT-7hKp5TByYjMpv5cL7Q8b96wAfyZd87GJRp81nmnAn5zHSei0aQWobsv9iI2_QbPLWi9luTLPDqr3FDcbU6OsWGUT6jm_G3I_6I71f--KFfMeNSN_H3tEuX7MGEV3gHNhCpqj90hCJkW-n_BHIC9lKmcwpU-vhVr3D2k-19YqL8z5GBntbNT0GbOoAkUBiMhLRQNDWRwiRrMDvDiaWz6LqL1_iRngUPRcvNhRVRH4Rt2DctE1VjaM6E_elPg-eoorBKouLeO3IeYNn7V4G5W_CQzXoesmBQEyTNsFmfVNif80AkIOG-67ke1WtRIZREm416B3-R4chfnCeANc6WwwvnK4ChmZe5-IBeesUmulUd2tkAcgLNlhPIv84VzB1JftgTwB8SLf9eAKGtKUB-GCVEtSjABqs49WryePmX8JIzR6yqGNC2Axghc-EHuhHM3ADOi85HaDDpy0c6cxmckC9rIDclxSBjU-2Jn2c0GopxRQWbkaGPcIvNXhzj1PBWLjqGwDy_ZAilqmjDBwKyKUYnoLcmsRpk6JHogi-kazdCEgavz37aBFAe-VlkYNkbvTrNhpKk2rhEiRHjoeI3ALerLKq7rLPLWlpveXPD0ko8rJQgONMrrZuCyacpGi-w3SjPji-znDOzaTz1kuSpTEOBYg4WDzuH0NXUvrTm2t21J_-O3EY6buyeK24Bw1UZaSBUeY5trzQp-rBv-jbBOuC48IGOUwezEQnNoBseqaZVjHStef9ztrmoapFtVr1ZNYlhdBopPtkg0PRqlJ8oBxZcIpGvX4Lryi2V49kb5tIjGkb8VwBvaVWGJKd8JnaspMfvk1WUbReZ5G7p_KG77g.rNrpaxCm2ax4uzMjyeNsezW6Xd6TM-jWC1apTq-BkXw\",\"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\":1776120872087},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyMjM3MiwiaWF0IjoxNzc2MTE5MDcyLCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiI4NDQxMWZjMC02YTJhLTRhNmMtOGQ0NS0zNTMxOTQ4MTM2YTUiLCJhdF9oYXNoIjoiTXNuSWhOMGthNlYtR01IOVgwVmF0QSJ9.lzfRpjis435jHqWjv_EYBi9_Vy3ZDSIcJpNIADLsMkXzYuhGolRrRInu1t-O8lGGINAK-NPQhU_aRN_O_S6DR2ROXQhazxPZigH2ReOT6cMao--QUXKfy9xXTsbIqlPeFEm9HKG3hrjNOJodrXs6s80UF3Nh7Qu6sIx02Z9ihHB_5O5T9F0HOiuRcGwHziLANhSlyaYMEdXHYkgfUnZOgXx8rAMNSpyeFsr6Hsr1Jb9DBoewjRj8ZLV6QRne4UG8jyrp-8HZrRDT193imO5I-rD_-6YWtALDO7ifx8IakLIQOhloqBR3PnyrAn4hExzljVzszVt3LdoSP2GGGSTZLA\"},\"dpopKeyThumbprint\":\"f5NUxcZhfik0T6Z5TLel7GRdtlu3Oiw3m3HUfAfzUTM\",\"issuedAtEpochMs\":1776119073088,\"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\":1776119072000,\"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}" + ], + [ + "stellaops.theme", + "system" + ], + [ + "stellaops.auth.session.info", + "{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"expiresAtEpochMs\":1776120872087,\"issuedAtEpochMs\":1776119073088,\"dpopKeyThumbprint\":\"f5NUxcZhfik0T6Z5TLel7GRdtlu3Oiw3m3HUfAfzUTM\",\"tenantId\":\"demo-prod\"}" + ], + [ + "stellaops.sidebar.preferences", + "{\"sidebarCollapsed\":false,\"collapsedGroups\":[\"evidence\",\"setup-admin\"],\"collapsedSections\":[]}" + ] + ], + "sessionStorageEntries": [ + [ + "stellaops.auth.session.full", + "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyMDg3MiwiaWF0IjoxNzc2MTE5MDcyLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiMzliN2M1ZmYtODRhYS00MmNiLWFhNjQtNmUyMGFiMWU3MGRmIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMTkwNzIsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.MHiRntRahfIwJMXhzh5xMpL46KM01jVwU7CPRkHHc_8PMgj8GtXAQX0DOWuWJ30Qgjbbu2mI7e4cUcWGC8Jj4XkNjEcns--l2rMkyhgG8CCu2vd5rUL-X7mbxGi-VzwNEp6lcaD1pi7SCWfPJuTmYMQs5xh2HXkMa3xMauzfzwDeuiFO_OTtrv_L-342-5PwYX8LS71a1ROVKKbuXHvzCcbNJa_7WtopNoIh9u8kSTRiPkizIeJkHwqBhC6bBg-Dxx6YE2Y-ax4TPdC8o5Alc3aGPi0RQboCDvy1FbIgwH1yYKJHBDXLlxU-cL0_ewsA91MYSStgdJ9h_9qpEKzswA\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.Fz-k6KlAa0wxHxePmM4jqkuuCDd72lICMquXMqTfI-Ru_npY05nYupTgxoqADorDdJEApvhc5HsrO89-gj55XVEaj38LjBdA0KnNhMlJcbc0CVCTtq0Bs0s7dBwn3znVnCA6aUmuCXrbb97s9kyBOhy2UBaa07jk7tHwnWzqV94wT2rLUSngM7-RqtpGWLVrQ1CBi1ge5qXW4aA9aec6YTZkJ4NFa4SagtrhFWlNOW5JuYytq_BN5m9CZsgZuuvXaKFTm00wY1LsPN0H9viFOPkDTt4fIQW3qGVIGuDR8jDaWdnNHfSJnAb_GAAhFnQmMd1I3NMPzyVusdxx6wO1Lw.KyOUCjObio0NfYglmlLoUg.Mm08l7mIFTibKFhfSyTcLMYUr4JpKV1L9Hc6hRa9yVZFzvXIxwfV3AXFBgIonjSUuV2RxZW7M36_DDdZExDR9EIWSV_4laoejCa5YqQtzZqH_NhIXGv5MtllgvuZ4i5OP6HmoIjD4DYkDaWOqVkdcc_5r7EtozIvPUNTeBptSRClHSrKV53oyV5EiIISLCuHjTRnvmb82QOZnc-oAbw45ost9cmCKcHylDjLyiX2DSLeatIlEhf47r-i7wj1MW0EjJB2Ur1oP51UpPMTVT1eZPKBAh5Ta8HEeARRsNSCeHRukip6rSDecUOgcWZsQDgHevy12eRPFGPu2eDuN7FOeSWZwX1NIWD7d0Hg70rWs__Q6G0Juf_Yys6HcsCWMoC4k8VyH3GbBRYHHu41qYrAdS8w_VJjaOMMSlGV4SGK12x5a2rAmTVgiK3AtCnoNCrUoCdQ4DQtKZCqxg5J-xQMD_nL7AbTEc-D8L7zURVH_2CE_7JTp9cAyL1PU98XvYkSd__nC9qURHnHKeVD34_euHoA9z6u1HRNYQxOeAlW19qreOMbAmf1XJTrcVEPHOMyJn5p5u4iwEZtYGpTRKv7g7UMBiEdd_S-idVumS8NLK0n9fdGF6qdKA7noA5PhkQ4hvWAOmEPJaQr6ipaE7qxdHN4-0dnkxT_KeCKBypjg9YbHRW9LKDR_eF7sMzWMcliZgO--T-p37nyUiRp6R2-sU3YuqEcsCD-4bDOXFY9xVzotPO-VWAx7VfIPSDixrmCNaZdEz87wbdFUJ5irEcdAXialv0L5kyagMzWkflI6yfpVzoe5PvAFad1R0WIdMISItAQlDZqFKWP6Myp7lbmiWey6OTRa0KcR2c4DrIPpSaXOb-KxpsJcq1I9RObAiYLgrZiMG2XlsUj6kMdQzr1Nh0c9pvlCBoVrLaIaIEIAD19pswtgg4lfYZlL1hxDVBCM-QAg0Edj5SJSyw-PM2YHRxhM9my0bvGlJA1PN79-S2RA6-mOhFteRFR_0QoM4Oxjba94kbs3ZjeRtqHN8iCu4sE4bNUj45pRO5R3-mGt5Jh5h6GSY4ZyoBGpH3CflN_8NVdkBGtHRtFP_6oEJFjY66twiSehs-fzVu3s1v5uH7q7SzJzmrh_eHT8cwREYFGsXcNr7C-xFxw1i7E8LnKghtPzZys7XMAJfq_qXQoRETkwFjmn-W8i_rp1biGZS9ifp9pNhLelzMLkzwT3REg8xoUqjdchUrtDgqB1f3OIWZ5XzXVSrX25AASwtoAuAo6aIRyxoBGpJAYO1dbQfoztFuvepMG_h8Grw7U1TNhr5WFhl3LEYxqb-qbtJx6cqneT3oSewDfALOCMqgITnNoGkALKANfoh-NUt2o7KYZzKHlymTzRuBbomClgxMOz3sJlg8w3JZCD-Yq7UEWZUurOE-YM541O4mL8eOPctOE7pBjVU9_tT7RQmDM2lbQX2_f1wbQZc2o9WV_f6TMScbjDcRH0jQ2S8B6Iy6mKcYMAauXIPphftt-AwuPATt-ecyps79rUOJHo_QZiA9VPE4LYuhtVUDDeQ92QMjNhz_095wK9sdtis_tGul1kh-B1B6Fi2N4I0cV3cXX5f1Gq0lQar3GHoOxbThgKJxRL0nR339QEipc084TRyG0ExWfXEZfus95fa-l0VC0xHdjN-we4TbGOm5jwEO7RZvUrBTbvcpXqUMycKJFnxXXp8XZRX4OSl92DxqsiAbyU9irqOCaXke3doPDbDUp2umgXmp2yhZU7EdeyPeE5YIDEL2mq7knQY5WaH9RwPQvzQT8VBcV75ScCtodPM_12yGpsu1P2qzsC3_OAzOK_Wv8sKWBuHuvhw06wgMdTiNJ9Qt4r5hyiH47usNtyrdbGUUTSHkpPfSzR7fMaVhH1koj1tqpM9bJixjBDhDGd-YgQFcPeW93aQvMoaSDKNeZSryWRXUwPaDpiolNulhTDVXFSqJM6pLa_yMw7zh1uJ6jt6Qhb2ime2P8LU1i56AD3k5dDZknVDfQYvSYRERNw3YP9pK7MYMQDkrlZ9DyR7Xx50L67z0JvvNHZ8j320IXWqhx4XpDeJnIKHc8qf5y0FOYKDnCAI5LQDro0UtYQ19kBoWxtLyweAlZ1OQU44gD8GFkQDfCuSeQKSSzEKLeUchRvyWaqsIidTIig1plq39O8nW1f3dt0escqp2smmO9UHh8nIaKO03jaW-vCb9lS8k8BlknxSWoj7174ibZKuJgFkbEe7w6UtoADn9kU9wlJ4yAKCW8MmIhCI3eR3Eu6T680qmNiIcSr3kZJBcP3FozXO5lsjmJfPmvTxwjwCpNrX-LOlp9Aw-mMiMpu-IXkTCVt8xxKwO0vdpXWup1HrGn1-5TpKXyx1cwjL-Nw25A4SW4eaTMVou-KHQwiez7XaAJmMwZluu9ChTmp46s7xFYIJapC5090BGMua2SVr1DnQWvFSqnutjL06XG8n_9CChEKbGi9QJYWrPdMeDQFnTndsdJM1CFguvrnxUm8WvZEjd3sIysugaJFepYFnrPtJktQ9Tn3JrgVBpVMmMc9G9WaXB4_eziq2F4nMQ8BPaDamBXZA_picqOmmynCtSlTz4UhYmoqIdSKRKgMcc0UI5vdDwdPEqvuaayXVb4DK86M2qLrfLnyDlp1K-U_iqtoMRce6_UqY_b2x7d-bovSl98eVn4yygamYi8OSYAgAzx0EpymXLy2SUCuo_qdBmsQiKs7U-5gUtJLN5q8aHq9zrulMidBlGAQP4C19I9k6A7CkbKzQerEr8J-2gzo81PA6YkkPwsFMQqcgn7668KH0SygTnMArz3D1Z9avrJGZQ0iSb9aDT0e4GtkWx00LTf4MX6xhSdvkveodgNwiz5Ti6-00Xicchc8yIatGWHktmEhKnxesZNdDM_dLvS4gEC6oo6puEc7M6Cx12xgt7-S-Rndrwk8E4DU2yDGW1FH9ZeDig8vGvqJxrTE0YcOjF9vk1h9jtUfPCEGSuKNG0f0qRl3V_zeRbdA9v0gwSY76o-gxez1tUJLuEHPgrvNor9zOosrzDX6WY92L2NIpnx63W9I81Hehj3ro9r8RrpsE0wBJ7QCUeLt1aI3tgxDsD_Fha8pmaQC9Q6v9qUFJ5-0_3BjEpKgrixJYTNWv1CzBt8THIfjh8H2rvknPvsEf3V_XBLJUQ3C04oNBb2k1UMBp92nYpOyA4ulvIvepf42k8V2wN11BF3v4bdIJakqAEU086ijVeEbVzjC365W53ZqcoOTHB_xsJT4aH4Oiw54J3ZcHVGoANQwazJW3KUJ5_MMVutFYXAsBpyV4l-SAbPF55XsVN7CCdK6LRIJ4Pz7OUhX66hIS5kZt_arYO_rHZSr4AyMQU-Pw4Tz-nEUAYLyYzDzr2MdhEFj-ED3NH4tXkpPYwuv81uvtEIZeIIGhbQ23BRKBtq4AGygzNiJf6ZRWXpXqNWYd8hDbIycTYzUaWVxEXM0W5f-v6sen9V-blAsGjHnH2g9_lEmEu-H1WdMv-frMQt8LYirg_7hir-pbLEwjb5j8uXp1orIJdvvdQwcaOs6jh1NOwjzYYHKhIoXWH2l8pQPwfctAMs4u8OmaaYRJGzG7-B-uAVcuw0a__yXb8YqCw3VO7N14Ir20IucluJ4vq_mHJDVVz3YM6dJtBWN1CLDnv6mGzCAh_7GpKi9XOCOY_sUDc3gr9aodgdwNKKrPK7m6JSD-6FgpLQz_sLzfi31sot-NQCuD5kgZW30X4iyeqI6r290HNaHA7Q-RKXfb-OVWtkr0Btj3qb9NuJJYiOtjam3x3tZHQta6o_7wchHJINJKckfJtnxVX3TOFzHebmkCcjaI23fEtg7dvTahcc7LXBhS1ls2dy5JPjTc9bjTrptXYlT-7hKp5TByYjMpv5cL7Q8b96wAfyZd87GJRp81nmnAn5zHSei0aQWobsv9iI2_QbPLWi9luTLPDqr3FDcbU6OsWGUT6jm_G3I_6I71f--KFfMeNSN_H3tEuX7MGEV3gHNhCpqj90hCJkW-n_BHIC9lKmcwpU-vhVr3D2k-19YqL8z5GBntbNT0GbOoAkUBiMhLRQNDWRwiRrMDvDiaWz6LqL1_iRngUPRcvNhRVRH4Rt2DctE1VjaM6E_elPg-eoorBKouLeO3IeYNn7V4G5W_CQzXoesmBQEyTNsFmfVNif80AkIOG-67ke1WtRIZREm416B3-R4chfnCeANc6WwwvnK4ChmZe5-IBeesUmulUd2tkAcgLNlhPIv84VzB1JftgTwB8SLf9eAKGtKUB-GCVEtSjABqs49WryePmX8JIzR6yqGNC2Axghc-EHuhHM3ADOi85HaDDpy0c6cxmckC9rIDclxSBjU-2Jn2c0GopxRQWbkaGPcIvNXhzj1PBWLjqGwDy_ZAilqmjDBwKyKUYnoLcmsRpk6JHogi-kazdCEgavz37aBFAe-VlkYNkbvTrNhpKk2rhEiRHjoeI3ALerLKq7rLPLWlpveXPD0ko8rJQgONMrrZuCyacpGi-w3SjPji-znDOzaTz1kuSpTEOBYg4WDzuH0NXUvrTm2t21J_-O3EY6buyeK24Bw1UZaSBUeY5trzQp-rBv-jbBOuC48IGOUwezEQnNoBseqaZVjHStef9ztrmoapFtVr1ZNYlhdBopPtkg0PRqlJ8oBxZcIpGvX4Lryi2V49kb5tIjGkb8VwBvaVWGJKd8JnaspMfvk1WUbReZ5G7p_KG77g.rNrpaxCm2ax4uzMjyeNsezW6Xd6TM-jWC1apTq-BkXw\",\"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\":1776120872087},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyMjM3MiwiaWF0IjoxNzc2MTE5MDcyLCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiI4NDQxMWZjMC02YTJhLTRhNmMtOGQ0NS0zNTMxOTQ4MTM2YTUiLCJhdF9oYXNoIjoiTXNuSWhOMGthNlYtR01IOVgwVmF0QSJ9.lzfRpjis435jHqWjv_EYBi9_Vy3ZDSIcJpNIADLsMkXzYuhGolRrRInu1t-O8lGGINAK-NPQhU_aRN_O_S6DR2ROXQhazxPZigH2ReOT6cMao--QUXKfy9xXTsbIqlPeFEm9HKG3hrjNOJodrXs6s80UF3Nh7Qu6sIx02Z9ihHB_5O5T9F0HOiuRcGwHziLANhSlyaYMEdXHYkgfUnZOgXx8rAMNSpyeFsr6Hsr1Jb9DBoewjRj8ZLV6QRne4UG8jyrp-8HZrRDT193imO5I-rD_-6YWtALDO7ifx8IakLIQOhloqBR3PnyrAn4hExzljVzszVt3LdoSP2GGGSTZLA\"},\"dpopKeyThumbprint\":\"f5NUxcZhfik0T6Z5TLel7GRdtlu3Oiw3m3HUfAfzUTM\",\"issuedAtEpochMs\":1776119073088,\"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\":1776119072000,\"freshAuthActive\":false,\"freshAuthExpiresAtEpochMs\":null}" + ], + [ + "stellaops:wasEverAuth", + "true" + ] + ] + }, + "events": { + "consoleErrors": [ + "Failed to load resource: the server responded with a status of 503 ()", + "Failed to load resource: the server responded with a status of 503 ()", + "Failed to load resource: the server responded with a status of 503 ()", + "Failed to load resource: the server responded with a status of 503 ()" + ], + "requestFailures": [], + "responseErrors": [ + { + "status": 503, + "method": "GET", + "url": "https://stella-ops.local/api/v1/scheduler/doctor/trends/categories/security?from=2025-04-18T22:24:33.125Z&to=2026-04-13T22:24:33.125Z", + "page": "https://stella-ops.local/" + }, + { + "status": 503, + "method": "GET", + "url": "https://stella-ops.local/api/v1/scheduler/doctor/trends/categories/platform?from=2025-04-18T22:24:33.125Z&to=2026-04-13T22:24:33.125Z", + "page": "https://stella-ops.local/" + }, + { + "status": 503, + "method": "GET", + "url": "https://stella-ops.local/api/v1/stella-assistant/glossary?locale=en-US", + "page": "https://stella-ops.local/" + }, + { + "status": 503, + "method": "GET", + "url": "https://stella-ops.local/api/v1/vulnerabilities/status", + "page": "https://stella-ops.local/" + } + ] + }, + "statePath": "src/Web/StellaOps.Web/output/playwright/live-setup-wizard-tokens.state.json" +} diff --git a/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-tokens.state.json b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-tokens.state.json new file mode 100644 index 000000000..491b82005 --- /dev/null +++ b/src/Web/StellaOps.Web/output/playwright/live-setup-wizard-tokens.state.json @@ -0,0 +1,38 @@ +{ + "cookies": [], + "origins": [ + { + "origin": "https://stella-ops.local", + "localStorage": [ + { + "name": "stellaops.auth.session.full", + "value": "{\"tokens\":{\"accessToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJhdCtqd3QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyMDg3MiwiaWF0IjoxNzc2MTE5MDcyLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIG9mZmxpbmVfYWNjZXNzIHVpLnJlYWQgdWkuYWRtaW4gdWkucHJlZmVyZW5jZXMucmVhZCB1aS5wcmVmZXJlbmNlcy53cml0ZSBhdXRob3JpdHk6dGVuYW50cy5yZWFkIGF1dGhvcml0eTp0ZW5hbnRzLndyaXRlIGF1dGhvcml0eTp1c2Vycy5yZWFkIGF1dGhvcml0eTp1c2Vycy53cml0ZSBhdXRob3JpdHk6cm9sZXMucmVhZCBhdXRob3JpdHk6cm9sZXMud3JpdGUgYXV0aG9yaXR5OmNsaWVudHMucmVhZCBhdXRob3JpdHk6Y2xpZW50cy53cml0ZSBhdXRob3JpdHk6dG9rZW5zLnJlYWQgYXV0aG9yaXR5OnRva2Vucy5yZXZva2UgYXV0aG9yaXR5OmJyYW5kaW5nLnJlYWQgYXV0aG9yaXR5OmJyYW5kaW5nLndyaXRlIGF1dGhvcml0eS5hdWRpdC5yZWFkIGdyYXBoOnJlYWQgc2JvbTpyZWFkIHNjYW5uZXI6cmVhZCBwb2xpY3k6cmVhZCBwb2xpY3k6c2ltdWxhdGUgcG9saWN5OmF1dGhvciBwb2xpY3k6cmV2aWV3IHBvbGljeTphcHByb3ZlIHBvbGljeTpydW4gcG9saWN5OmFjdGl2YXRlIHBvbGljeTphdWRpdCBwb2xpY3k6ZWRpdCBwb2xpY3k6b3BlcmF0ZSBwb2xpY3k6cHVibGlzaCBhaXJnYXA6c2VhbCBhaXJnYXA6c3RhdHVzOnJlYWQgb3JjaDpyZWFkIG9yY2g6b3BlcmF0ZSBvcmNoOnF1b3RhIGFuYWx5dGljcy5yZWFkIGFkdmlzb3J5OnJlYWQgYWR2aXNvcnktYWk6dmlldyBhZHZpc29yeS1haTpvcGVyYXRlIHZleDpyZWFkIHZleGh1YjpyZWFkIGV4Y2VwdGlvbnM6cmVhZCBleGNlcHRpb25zOmFwcHJvdmUgYW9jOnZlcmlmeSBmaW5kaW5nczpyZWFkIHJlbGVhc2U6cmVhZCByZWxlYXNlOndyaXRlIHJlbGVhc2U6cHVibGlzaCBzY2hlZHVsZXI6cmVhZCBzY2hlZHVsZXI6b3BlcmF0ZSBub3RpZnkudmlld2VyIG5vdGlmeS5vcGVyYXRvciBub3RpZnkuYWRtaW4gbm90aWZ5LmVzY2FsYXRlIGV2aWRlbmNlOnJlYWQgZXhwb3J0LnZpZXdlciBleHBvcnQub3BlcmF0b3IgZXhwb3J0LmFkbWluIHZ1bG46dmlldyB2dWxuOmludmVzdGlnYXRlIHZ1bG46b3BlcmF0ZSB2dWxuOmF1ZGl0IHBsYXRmb3JtLmNvbnRleHQucmVhZCBwbGF0Zm9ybS5jb250ZXh0LndyaXRlIGRvY3RvcjpydW4gZG9jdG9yOmFkbWluIG9wcy5oZWFsdGggaW50ZWdyYXRpb246cmVhZCBpbnRlZ3JhdGlvbjp3cml0ZSBpbnRlZ3JhdGlvbjpvcGVyYXRlIHBhY2tzLnJlYWQgcGFja3Mud3JpdGUgcGFja3MucnVuIHBhY2tzLmFwcHJvdmUgcmVnaXN0cnkuYWRtaW4gdGltZWxpbmU6cmVhZCB0aW1lbGluZTp3cml0ZSB0cnVzdDpyZWFkIHRydXN0OndyaXRlIHRydXN0OmFkbWluIHNpZ25lcjpyZWFkIHNpZ25lcjpzaWduIHNpZ25lcjpyb3RhdGUgc2lnbmVyOmFkbWluIiwianRpIjoiMzliN2M1ZmYtODRhYS00MmNiLWFhNjQtNmUyMGFiMWU3MGRmIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsInJvbGUiOiJhZG1pbiIsInN0ZWxsYW9wczp0ZW5hbnQiOiJkZW1vLXByb2QiLCJhdXRoX3RpbWUiOjE3NzYxMTkwNzIsIm9pX3Byc3QiOiJzdGVsbGEtb3BzLXVpIiwiY2xpZW50X2lkIjoic3RlbGxhLW9wcy11aSJ9.MHiRntRahfIwJMXhzh5xMpL46KM01jVwU7CPRkHHc_8PMgj8GtXAQX0DOWuWJ30Qgjbbu2mI7e4cUcWGC8Jj4XkNjEcns--l2rMkyhgG8CCu2vd5rUL-X7mbxGi-VzwNEp6lcaD1pi7SCWfPJuTmYMQs5xh2HXkMa3xMauzfzwDeuiFO_OTtrv_L-342-5PwYX8LS71a1ROVKKbuXHvzCcbNJa_7WtopNoIh9u8kSTRiPkizIeJkHwqBhC6bBg-Dxx6YE2Y-ax4TPdC8o5Alc3aGPi0RQboCDvy1FbIgwH1yYKJHBDXLlxU-cL0_ewsA91MYSStgdJ9h_9qpEKzswA\",\"tokenType\":\"Bearer\",\"refreshToken\":\"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJraWQiOiIwV0lMWkRTT0RETVJLNk42VlRfN09KWlgwVzhDQVI4VU1ZWTI5R0tBIiwidHlwIjoib2lfcmVmdCtqd3QiLCJjdHkiOiJKV1QifQ.Fz-k6KlAa0wxHxePmM4jqkuuCDd72lICMquXMqTfI-Ru_npY05nYupTgxoqADorDdJEApvhc5HsrO89-gj55XVEaj38LjBdA0KnNhMlJcbc0CVCTtq0Bs0s7dBwn3znVnCA6aUmuCXrbb97s9kyBOhy2UBaa07jk7tHwnWzqV94wT2rLUSngM7-RqtpGWLVrQ1CBi1ge5qXW4aA9aec6YTZkJ4NFa4SagtrhFWlNOW5JuYytq_BN5m9CZsgZuuvXaKFTm00wY1LsPN0H9viFOPkDTt4fIQW3qGVIGuDR8jDaWdnNHfSJnAb_GAAhFnQmMd1I3NMPzyVusdxx6wO1Lw.KyOUCjObio0NfYglmlLoUg.Mm08l7mIFTibKFhfSyTcLMYUr4JpKV1L9Hc6hRa9yVZFzvXIxwfV3AXFBgIonjSUuV2RxZW7M36_DDdZExDR9EIWSV_4laoejCa5YqQtzZqH_NhIXGv5MtllgvuZ4i5OP6HmoIjD4DYkDaWOqVkdcc_5r7EtozIvPUNTeBptSRClHSrKV53oyV5EiIISLCuHjTRnvmb82QOZnc-oAbw45ost9cmCKcHylDjLyiX2DSLeatIlEhf47r-i7wj1MW0EjJB2Ur1oP51UpPMTVT1eZPKBAh5Ta8HEeARRsNSCeHRukip6rSDecUOgcWZsQDgHevy12eRPFGPu2eDuN7FOeSWZwX1NIWD7d0Hg70rWs__Q6G0Juf_Yys6HcsCWMoC4k8VyH3GbBRYHHu41qYrAdS8w_VJjaOMMSlGV4SGK12x5a2rAmTVgiK3AtCnoNCrUoCdQ4DQtKZCqxg5J-xQMD_nL7AbTEc-D8L7zURVH_2CE_7JTp9cAyL1PU98XvYkSd__nC9qURHnHKeVD34_euHoA9z6u1HRNYQxOeAlW19qreOMbAmf1XJTrcVEPHOMyJn5p5u4iwEZtYGpTRKv7g7UMBiEdd_S-idVumS8NLK0n9fdGF6qdKA7noA5PhkQ4hvWAOmEPJaQr6ipaE7qxdHN4-0dnkxT_KeCKBypjg9YbHRW9LKDR_eF7sMzWMcliZgO--T-p37nyUiRp6R2-sU3YuqEcsCD-4bDOXFY9xVzotPO-VWAx7VfIPSDixrmCNaZdEz87wbdFUJ5irEcdAXialv0L5kyagMzWkflI6yfpVzoe5PvAFad1R0WIdMISItAQlDZqFKWP6Myp7lbmiWey6OTRa0KcR2c4DrIPpSaXOb-KxpsJcq1I9RObAiYLgrZiMG2XlsUj6kMdQzr1Nh0c9pvlCBoVrLaIaIEIAD19pswtgg4lfYZlL1hxDVBCM-QAg0Edj5SJSyw-PM2YHRxhM9my0bvGlJA1PN79-S2RA6-mOhFteRFR_0QoM4Oxjba94kbs3ZjeRtqHN8iCu4sE4bNUj45pRO5R3-mGt5Jh5h6GSY4ZyoBGpH3CflN_8NVdkBGtHRtFP_6oEJFjY66twiSehs-fzVu3s1v5uH7q7SzJzmrh_eHT8cwREYFGsXcNr7C-xFxw1i7E8LnKghtPzZys7XMAJfq_qXQoRETkwFjmn-W8i_rp1biGZS9ifp9pNhLelzMLkzwT3REg8xoUqjdchUrtDgqB1f3OIWZ5XzXVSrX25AASwtoAuAo6aIRyxoBGpJAYO1dbQfoztFuvepMG_h8Grw7U1TNhr5WFhl3LEYxqb-qbtJx6cqneT3oSewDfALOCMqgITnNoGkALKANfoh-NUt2o7KYZzKHlymTzRuBbomClgxMOz3sJlg8w3JZCD-Yq7UEWZUurOE-YM541O4mL8eOPctOE7pBjVU9_tT7RQmDM2lbQX2_f1wbQZc2o9WV_f6TMScbjDcRH0jQ2S8B6Iy6mKcYMAauXIPphftt-AwuPATt-ecyps79rUOJHo_QZiA9VPE4LYuhtVUDDeQ92QMjNhz_095wK9sdtis_tGul1kh-B1B6Fi2N4I0cV3cXX5f1Gq0lQar3GHoOxbThgKJxRL0nR339QEipc084TRyG0ExWfXEZfus95fa-l0VC0xHdjN-we4TbGOm5jwEO7RZvUrBTbvcpXqUMycKJFnxXXp8XZRX4OSl92DxqsiAbyU9irqOCaXke3doPDbDUp2umgXmp2yhZU7EdeyPeE5YIDEL2mq7knQY5WaH9RwPQvzQT8VBcV75ScCtodPM_12yGpsu1P2qzsC3_OAzOK_Wv8sKWBuHuvhw06wgMdTiNJ9Qt4r5hyiH47usNtyrdbGUUTSHkpPfSzR7fMaVhH1koj1tqpM9bJixjBDhDGd-YgQFcPeW93aQvMoaSDKNeZSryWRXUwPaDpiolNulhTDVXFSqJM6pLa_yMw7zh1uJ6jt6Qhb2ime2P8LU1i56AD3k5dDZknVDfQYvSYRERNw3YP9pK7MYMQDkrlZ9DyR7Xx50L67z0JvvNHZ8j320IXWqhx4XpDeJnIKHc8qf5y0FOYKDnCAI5LQDro0UtYQ19kBoWxtLyweAlZ1OQU44gD8GFkQDfCuSeQKSSzEKLeUchRvyWaqsIidTIig1plq39O8nW1f3dt0escqp2smmO9UHh8nIaKO03jaW-vCb9lS8k8BlknxSWoj7174ibZKuJgFkbEe7w6UtoADn9kU9wlJ4yAKCW8MmIhCI3eR3Eu6T680qmNiIcSr3kZJBcP3FozXO5lsjmJfPmvTxwjwCpNrX-LOlp9Aw-mMiMpu-IXkTCVt8xxKwO0vdpXWup1HrGn1-5TpKXyx1cwjL-Nw25A4SW4eaTMVou-KHQwiez7XaAJmMwZluu9ChTmp46s7xFYIJapC5090BGMua2SVr1DnQWvFSqnutjL06XG8n_9CChEKbGi9QJYWrPdMeDQFnTndsdJM1CFguvrnxUm8WvZEjd3sIysugaJFepYFnrPtJktQ9Tn3JrgVBpVMmMc9G9WaXB4_eziq2F4nMQ8BPaDamBXZA_picqOmmynCtSlTz4UhYmoqIdSKRKgMcc0UI5vdDwdPEqvuaayXVb4DK86M2qLrfLnyDlp1K-U_iqtoMRce6_UqY_b2x7d-bovSl98eVn4yygamYi8OSYAgAzx0EpymXLy2SUCuo_qdBmsQiKs7U-5gUtJLN5q8aHq9zrulMidBlGAQP4C19I9k6A7CkbKzQerEr8J-2gzo81PA6YkkPwsFMQqcgn7668KH0SygTnMArz3D1Z9avrJGZQ0iSb9aDT0e4GtkWx00LTf4MX6xhSdvkveodgNwiz5Ti6-00Xicchc8yIatGWHktmEhKnxesZNdDM_dLvS4gEC6oo6puEc7M6Cx12xgt7-S-Rndrwk8E4DU2yDGW1FH9ZeDig8vGvqJxrTE0YcOjF9vk1h9jtUfPCEGSuKNG0f0qRl3V_zeRbdA9v0gwSY76o-gxez1tUJLuEHPgrvNor9zOosrzDX6WY92L2NIpnx63W9I81Hehj3ro9r8RrpsE0wBJ7QCUeLt1aI3tgxDsD_Fha8pmaQC9Q6v9qUFJ5-0_3BjEpKgrixJYTNWv1CzBt8THIfjh8H2rvknPvsEf3V_XBLJUQ3C04oNBb2k1UMBp92nYpOyA4ulvIvepf42k8V2wN11BF3v4bdIJakqAEU086ijVeEbVzjC365W53ZqcoOTHB_xsJT4aH4Oiw54J3ZcHVGoANQwazJW3KUJ5_MMVutFYXAsBpyV4l-SAbPF55XsVN7CCdK6LRIJ4Pz7OUhX66hIS5kZt_arYO_rHZSr4AyMQU-Pw4Tz-nEUAYLyYzDzr2MdhEFj-ED3NH4tXkpPYwuv81uvtEIZeIIGhbQ23BRKBtq4AGygzNiJf6ZRWXpXqNWYd8hDbIycTYzUaWVxEXM0W5f-v6sen9V-blAsGjHnH2g9_lEmEu-H1WdMv-frMQt8LYirg_7hir-pbLEwjb5j8uXp1orIJdvvdQwcaOs6jh1NOwjzYYHKhIoXWH2l8pQPwfctAMs4u8OmaaYRJGzG7-B-uAVcuw0a__yXb8YqCw3VO7N14Ir20IucluJ4vq_mHJDVVz3YM6dJtBWN1CLDnv6mGzCAh_7GpKi9XOCOY_sUDc3gr9aodgdwNKKrPK7m6JSD-6FgpLQz_sLzfi31sot-NQCuD5kgZW30X4iyeqI6r290HNaHA7Q-RKXfb-OVWtkr0Btj3qb9NuJJYiOtjam3x3tZHQta6o_7wchHJINJKckfJtnxVX3TOFzHebmkCcjaI23fEtg7dvTahcc7LXBhS1ls2dy5JPjTc9bjTrptXYlT-7hKp5TByYjMpv5cL7Q8b96wAfyZd87GJRp81nmnAn5zHSei0aQWobsv9iI2_QbPLWi9luTLPDqr3FDcbU6OsWGUT6jm_G3I_6I71f--KFfMeNSN_H3tEuX7MGEV3gHNhCpqj90hCJkW-n_BHIC9lKmcwpU-vhVr3D2k-19YqL8z5GBntbNT0GbOoAkUBiMhLRQNDWRwiRrMDvDiaWz6LqL1_iRngUPRcvNhRVRH4Rt2DctE1VjaM6E_elPg-eoorBKouLeO3IeYNn7V4G5W_CQzXoesmBQEyTNsFmfVNif80AkIOG-67ke1WtRIZREm416B3-R4chfnCeANc6WwwvnK4ChmZe5-IBeesUmulUd2tkAcgLNlhPIv84VzB1JftgTwB8SLf9eAKGtKUB-GCVEtSjABqs49WryePmX8JIzR6yqGNC2Axghc-EHuhHM3ADOi85HaDDpy0c6cxmckC9rIDclxSBjU-2Jn2c0GopxRQWbkaGPcIvNXhzj1PBWLjqGwDy_ZAilqmjDBwKyKUYnoLcmsRpk6JHogi-kazdCEgavz37aBFAe-VlkYNkbvTrNhpKk2rhEiRHjoeI3ALerLKq7rLPLWlpveXPD0ko8rJQgONMrrZuCyacpGi-w3SjPji-znDOzaTz1kuSpTEOBYg4WDzuH0NXUvrTm2t21J_-O3EY6buyeK24Bw1UZaSBUeY5trzQp-rBv-jbBOuC48IGOUwezEQnNoBseqaZVjHStef9ztrmoapFtVr1ZNYlhdBopPtkg0PRqlJ8oBxZcIpGvX4Lryi2V49kb5tIjGkb8VwBvaVWGJKd8JnaspMfvk1WUbReZ5G7p_KG77g.rNrpaxCm2ax4uzMjyeNsezW6Xd6TM-jWC1apTq-BkXw\",\"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\":1776120872087},\"identity\":{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"name\":\"admin\",\"roles\":[],\"idToken\":\"eyJhbGciOiJSUzI1NiIsImtpZCI6IlRDNktEWUFZTFNETzdMWkhfNTBNTjJTU1pOQl9JUEhEWUNRRElMUEEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2F1dGhvcml0eS5zdGVsbGEtb3BzLmxvY2FsLyIsImV4cCI6MTc3NjEyMjM3MiwiaWF0IjoxNzc2MTE5MDcyLCJhdWQiOiJzdGVsbGEtb3BzLXVpIiwic3ViIjoiNTdlMjMzNjQyODc0NDdkNmFlZDMxY2EzZjYxMTVlZTgiLCJuYW1lIjoiYWRtaW4iLCJhenAiOiJzdGVsbGEtb3BzLXVpIiwibm9uY2UiOiI4NDQxMWZjMC02YTJhLTRhNmMtOGQ0NS0zNTMxOTQ4MTM2YTUiLCJhdF9oYXNoIjoiTXNuSWhOMGthNlYtR01IOVgwVmF0QSJ9.lzfRpjis435jHqWjv_EYBi9_Vy3ZDSIcJpNIADLsMkXzYuhGolRrRInu1t-O8lGGINAK-NPQhU_aRN_O_S6DR2ROXQhazxPZigH2ReOT6cMao--QUXKfy9xXTsbIqlPeFEm9HKG3hrjNOJodrXs6s80UF3Nh7Qu6sIx02Z9ihHB_5O5T9F0HOiuRcGwHziLANhSlyaYMEdXHYkgfUnZOgXx8rAMNSpyeFsr6Hsr1Jb9DBoewjRj8ZLV6QRne4UG8jyrp-8HZrRDT193imO5I-rD_-6YWtALDO7ifx8IakLIQOhloqBR3PnyrAn4hExzljVzszVt3LdoSP2GGGSTZLA\"},\"dpopKeyThumbprint\":\"f5NUxcZhfik0T6Z5TLel7GRdtlu3Oiw3m3HUfAfzUTM\",\"issuedAtEpochMs\":1776119073088,\"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\":1776119072000,\"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}" + }, + { + "name": "stellaops.theme", + "value": "system" + }, + { + "name": "stellaops.auth.session.info", + "value": "{\"subject\":\"57e23364287447d6aed31ca3f6115ee8\",\"expiresAtEpochMs\":1776120872087,\"issuedAtEpochMs\":1776119073088,\"dpopKeyThumbprint\":\"f5NUxcZhfik0T6Z5TLel7GRdtlu3Oiw3m3HUfAfzUTM\",\"tenantId\":\"demo-prod\"}" + }, + { + "name": "stellaops.sidebar.preferences", + "value": "{\"sidebarCollapsed\":false,\"collapsedGroups\":[\"evidence\",\"setup-admin\"],\"collapsedSections\":[]}" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/Web/StellaOps.Web/scripts/live-integrations-ui-bootstrap.mjs b/src/Web/StellaOps.Web/scripts/live-integrations-ui-bootstrap.mjs new file mode 100644 index 000000000..485874912 --- /dev/null +++ b/src/Web/StellaOps.Web/scripts/live-integrations-ui-bootstrap.mjs @@ -0,0 +1,849 @@ +import { mkdir, writeFile } from 'node:fs/promises'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +import { chromium, request as playwrightRequest } from 'playwright'; + +import { + authenticateFrontdoor, + createAuthenticatedContext, + getSessionStorageEntries, +} from './live-frontdoor-auth.mjs'; + +const webRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); +const outputDir = path.join(webRoot, 'output', 'playwright'); +const outputPath = path.join(outputDir, 'live-integrations-ui-bootstrap.json'); +const authStatePath = path.join(outputDir, 'live-integrations-ui-bootstrap.state.json'); +const authReportPath = path.join(outputDir, 'live-integrations-ui-bootstrap.auth.json'); + +const baseUrl = process.env.STELLAOPS_FRONTDOOR_BASE_URL?.trim() || 'https://stella-ops.local'; +const scopeQuery = process.env.STELLAOPS_SCOPE_QUERY?.trim() || 'tenant=demo-prod®ions=apac,eu-west,us-east,us-west'; +const includeGitLab = (process.env.STELLAOPS_UI_BOOTSTRAP_INCLUDE_GITLAB || 'true').toLowerCase() !== 'false'; +const gitLabStageSecrets = (process.env.STELLAOPS_UI_BOOTSTRAP_GITLAB_STAGE_SECRETS || 'true').toLowerCase() !== 'false'; +const resetExisting = (process.env.STELLAOPS_UI_BOOTSTRAP_RESET_EXISTING || 'false').toLowerCase() === 'true'; +const gitLabAccessToken = process.env.STELLAOPS_UI_BOOTSTRAP_GITLAB_ACCESS_TOKEN?.trim() || ''; +const gitLabRegistryBasic = process.env.STELLAOPS_UI_BOOTSTRAP_GITLAB_REGISTRY_BASIC?.trim() || ''; +const headless = (process.env.STELLAOPS_UI_BOOTSTRAP_HEADLESS || 'true').toLowerCase() !== 'false'; + +/** + * Canonical local lane definitions mirrored from scripts/register-local-integrations.ps1. + * Creation happens through the UI wizard; API calls are used only for idempotency and verification. + */ +const integrationDefinitions = [ + { + name: 'Local Harbor Fixture', + route: 'registry', + provider: 'Harbor', + endpoint: 'http://harbor-fixture.stella-ops.local', + authRefUri: '', + organizationId: 'local-fixtures', + namespaces: ['local-fixtures'], + tagPatterns: ['release-*'], + tags: ['local', 'scratch-setup', 'registry'], + }, + { + name: 'Local Docker Registry', + route: 'registry', + provider: 'Docker Registry / Hub', + endpoint: 'http://registry.stella-ops.local:5000', + authRefUri: '', + organizationId: '', + namespaces: [], + tagPatterns: [], + tags: ['local', 'scratch-setup', 'registry'], + }, + { + name: 'Local Nexus Registry', + route: 'registry', + provider: 'Nexus', + endpoint: 'http://nexus.stella-ops.local:8081', + authRefUri: '', + organizationId: '', + namespaces: [], + tagPatterns: [], + tags: ['local', 'scratch-setup', 'registry'], + }, + { + name: 'Local GitHub App Fixture', + route: 'scm', + provider: 'GitHub App', + endpoint: 'http://github-app-fixture.stella-ops.local', + authRefUri: '', + organizationId: 'local-fixtures', + repositories: ['local-fixtures/demo'], + branches: ['main'], + configFields: { + appId: '424242', + installationId: '424243', + }, + tags: ['local', 'scratch-setup', 'scm'], + }, + { + name: 'Local Gitea Server', + route: 'scm', + provider: 'Gitea', + endpoint: 'http://gitea.stella-ops.local:3000', + authRefUri: '', + organizationId: 'local', + repositories: ['local/demo'], + branches: ['main'], + tags: ['local', 'scratch-setup', 'scm'], + }, + { + name: 'Local Jenkins', + route: 'ci', + provider: 'Jenkins', + endpoint: 'http://jenkins.stella-ops.local:8080', + authRefUri: '', + organizationId: '', + tags: ['local', 'scratch-setup', 'cicd'], + }, + { + name: 'Local eBPF Runtime Host', + route: 'host', + provider: 'eBPF Agent', + endpoint: 'http://runtime-host-fixture.stella-ops.local', + authRefUri: '', + organizationId: '', + tags: ['local', 'scratch-setup', 'runtime-host'], + }, + { + name: 'Local StellaOps Mirror', + route: 'feed', + provider: 'StellaOps Mirror', + endpoint: 'http://concelier.stella-ops.local', + authRefUri: '', + organizationId: '', + tags: ['local', 'scratch-setup', 'feed-mirror'], + }, + { + name: 'Local NVD Mirror', + route: 'feed', + provider: 'NVD Mirror', + endpoint: 'http://concelier.stella-ops.local', + authRefUri: '', + organizationId: '', + tags: ['local', 'scratch-setup', 'feed-mirror'], + }, + { + name: 'Local OSV Mirror', + route: 'feed', + provider: 'OSV Mirror', + endpoint: 'http://concelier.stella-ops.local', + authRefUri: '', + organizationId: '', + tags: ['local', 'scratch-setup', 'feed-mirror'], + }, + { + name: 'Local Vault', + route: 'secrets', + provider: 'HashiCorp Vault', + endpoint: 'http://vault.stella-ops.local:8200', + authRefUri: '', + organizationId: '', + tags: ['local', 'scratch-setup', 'secrets'], + }, + { + name: 'Local Consul', + route: 'secrets', + provider: 'HashiCorp Consul', + endpoint: 'http://consul.stella-ops.local:8500', + authRefUri: '', + organizationId: '', + tags: ['local', 'scratch-setup', 'secrets'], + }, + { + name: 'Local MinIO', + route: 'storage', + provider: 'S3-Compatible Storage', + endpoint: 'http://minio.stella-ops.local:9000', + authRefUri: '', + organizationId: '', + tags: ['local', 'scratch-setup', 'storage'], + }, +]; + +if (includeGitLab) { + integrationDefinitions.push( + { + name: 'Local GitLab Server', + route: 'scm', + provider: 'GitLab Server', + endpoint: 'http://gitlab.stella-ops.local:8929', + authRefUri: gitLabStageSecrets && gitLabAccessToken ? '' : 'authref://vault/gitlab#access-token', + organizationId: 'root', + repositories: ['root/local-demo'], + branches: ['main'], + secretStaging: gitLabStageSecrets && gitLabAccessToken + ? { + targetName: 'Local Vault', + bundleId: 'gitlab-server', + logicalPath: 'gitlab/server', + entries: { + 'access-token': gitLabAccessToken, + }, + } + : null, + tags: ['local', 'scratch-setup', 'scm'], + }, + { + name: 'Local GitLab CI', + route: 'ci', + provider: 'GitLab CI', + endpoint: 'http://gitlab.stella-ops.local:8929', + authRefUri: gitLabStageSecrets && gitLabAccessToken ? '' : 'authref://vault/gitlab#access-token', + organizationId: 'root', + secretStaging: gitLabStageSecrets && gitLabAccessToken + ? { + targetName: 'Local Vault', + bundleId: 'gitlab-ci', + logicalPath: 'gitlab/ci', + entries: { + 'access-token': gitLabAccessToken, + }, + } + : null, + tags: ['local', 'scratch-setup', 'cicd'], + }, + { + name: 'Local GitLab Container Registry', + route: 'registry', + provider: 'GitLab Container Registry', + endpoint: 'http://gitlab.stella-ops.local:5050', + authRefUri: gitLabStageSecrets && gitLabRegistryBasic ? '' : 'authref://vault/gitlab#registry-basic', + organizationId: 'root', + namespaces: ['root'], + tagPatterns: ['*'], + secretStaging: gitLabStageSecrets && gitLabRegistryBasic + ? { + targetName: 'Local Vault', + bundleId: 'gitlab-registry', + logicalPath: 'gitlab/registry', + entries: { + 'registry-basic': gitLabRegistryBasic, + }, + } + : null, + tags: ['local', 'scratch-setup', 'registry'], + }, + ); +} + +function scopedUrl(route) { + const separator = route.includes('?') ? '&' : '?'; + return `${baseUrl}${route}${separator}${scopeQuery}`; +} + +function integrationUrl(id) { + return scopedUrl(`/setup/integrations/${id}`); +} + +function integrationCredentialsUrl(id) { + return `${integrationUrl(id)}&tab=credentials`; +} + +function onboardingUrl(route) { + return scopedUrl(`/setup/integrations/onboarding/${route}`); +} + +async function settle(page, waitMs = 750) { + await page.waitForLoadState('domcontentloaded', { timeout: 20_000 }).catch(() => {}); + await page.waitForTimeout(waitMs); +} + +function getAccessToken(authReport) { + const fullSessionEntry = getSessionStorageEntries(authReport) + .find(([key]) => key === 'stellaops.auth.session.full'); + if (!fullSessionEntry) { + return null; + } + + try { + const parsed = JSON.parse(fullSessionEntry[1]); + return parsed?.tokens?.accessToken ?? null; + } catch { + return null; + } +} + +async function persistSummary(summary) { + summary.lastUpdatedAtUtc = new Date().toISOString(); + await writeFile(outputPath, `${JSON.stringify(summary, null, 2)}\n`, 'utf8'); +} + +async function headingText(page) { + const headings = page.locator('h1, h2'); + const count = await headings.count(); + for (let index = 0; index < Math.min(count, 6); index += 1) { + const text = (await headings.nth(index).innerText().catch(() => '')).trim(); + if (text) { + return text; + } + } + + return ''; +} + +async function captureSnapshot(page, label) { + const notices = await page + .locator('[role="alert"], .check-item, .result-card, .detail-state, .empty-state') + .evaluateAll((nodes) => + nodes + .map((node) => (node.textContent || '').trim().replace(/\s+/g, ' ')) + .filter(Boolean) + .slice(0, 12), + ) + .catch(() => []); + + return { + label, + url: page.url(), + title: await page.title(), + heading: await headingText(page), + notices, + }; +} + +async function createApiContext(token) { + return playwrightRequest.newContext({ + baseURL: baseUrl, + ignoreHTTPSErrors: true, + extraHTTPHeaders: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json', + }, + }); +} + +async function listIntegrations(apiContext) { + const response = await apiContext.get('/api/v1/integrations?pageSize=200'); + if (!response.ok()) { + throw new Error(`Failed to list integrations: ${response.status()} ${await response.text()}`); + } + + const body = await response.json(); + return Array.isArray(body?.items) ? body.items : []; +} + +async function findExistingIntegration(apiContext, definition) { + const items = await listIntegrations(apiContext); + return items.find((item) => item.provider === providerCode(definition.provider) && item.endpoint === definition.endpoint) ?? null; +} + +function matchesManagedDefinition(item) { + return integrationDefinitions.some( + (definition) => + item.provider === providerCode(definition.provider) + && item.endpoint === definition.endpoint, + ); +} + +async function invokeUiButtonIfVisible(page, namePattern) { + const button = page.getByRole('button', { name: namePattern }); + if (!(await button.isVisible().catch(() => false))) { + return false; + } + + await button.click({ timeout: 10_000 }); + return true; +} + +function providerCode(providerName) { + const map = { + Harbor: 100, + 'Docker Registry / Hub': 104, + Nexus: 107, + 'GitLab Container Registry': 109, + 'GitHub App': 200, + 'GitLab Server': 201, + Gitea: 203, + 'GitLab CI': 301, + Jenkins: 302, + 'eBPF Agent': 500, + 'HashiCorp Vault': 550, + 'HashiCorp Consul': 551, + 'StellaOps Mirror': 600, + 'NVD Mirror': 601, + 'OSV Mirror': 602, + 'S3-Compatible Storage': 450, + }; + + const code = map[providerName]; + if (typeof code !== 'number') { + throw new Error(`Unknown provider code for ${providerName}`); + } + + return code; +} + +async function fillLabeledControl(page, label, value) { + const locator = page.getByLabel(label, { exact: true }); + if (!(await locator.isVisible().catch(() => false))) { + return false; + } + + await locator.fill(value); + return true; +} + +async function fillById(page, selector, value) { + if (!value || value.length === 0) { + return false; + } + + const locator = page.locator(selector); + if (!(await locator.isVisible().catch(() => false))) { + return false; + } + + await locator.fill(value); + await page.waitForTimeout(150); + return true; +} + +async function maybeFill(page, label, value) { + if (!value || value.length === 0) { + return false; + } + + return fillLabeledControl(page, label, value); +} + +async function addTags(page, tags) { + if (!Array.isArray(tags) || tags.length === 0) { + return; + } + + const tagInput = page.getByPlaceholder('Add tag...'); + if (!(await tagInput.isVisible().catch(() => false))) { + return; + } + + for (const tag of tags) { + await tagInput.fill(tag); + await page.getByRole('button', { name: /^Add$/ }).click({ timeout: 10_000 }); + } +} + +async function waitForNextEnabled(page, timeoutMs = 20_000) { + const nextButton = page.getByRole('button', { name: /^Next$/ }); + const startedAt = Date.now(); + + while (Date.now() - startedAt < timeoutMs) { + if (await nextButton.isVisible().catch(() => false) && await nextButton.isEnabled().catch(() => false)) { + return nextButton; + } + + await page.waitForTimeout(250); + } + + throw new Error(`Timed out waiting for Next button to enable after ${timeoutMs}ms`); +} + +async function selectProviderIfNeeded(page, definition) { + const providerHeading = page.getByRole('heading', { name: new RegExp(`Select .* Provider`, 'i') }); + if (await providerHeading.isVisible().catch(() => false)) { + await page.getByRole('button', { name: new RegExp(definition.provider.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i') }) + .click({ timeout: 10_000 }); + const nextButton = await waitForNextEnabled(page); + await nextButton.click({ timeout: 10_000 }); + await settle(page); + } + + await page.getByRole('heading', { name: /Connection & Credentials/i }).waitFor({ timeout: 15_000 }); +} + +async function populateConnection(page, definition) { + await fillById(page, '#endpoint', definition.endpoint); + await fillById(page, '#authRefUri', definition.authRefUri); + await populateSecretStaging(page, definition); + await fillById(page, '#organizationId', definition.organizationId); + + if (definition.configFields) { + for (const [fieldId, value] of Object.entries(definition.configFields)) { + await fillById(page, `#config-${fieldId}`, value); + } + } + + const nextButton = await waitForNextEnabled(page); + await nextButton.click({ timeout: 10_000 }); + await page.getByRole('heading', { name: /Discovery Scope/i }).waitFor({ timeout: 15_000 }); +} + +async function populateSecretStaging(page, definition) { + if (!definition.secretStaging) { + return; + } + + const toggle = page.locator('#secret-staging-enabled'); + if (!(await toggle.isVisible().catch(() => false))) { + throw new Error(`Secret staging UI is not available for ${definition.name}`); + } + + if (!(await toggle.isChecked())) { + await toggle.check(); + await page.waitForTimeout(200); + } + + const targetValue = await resolveSecretTargetValue(page, definition.secretStaging.targetName); + if (!targetValue) { + throw new Error(`No matching secret-authority target '${definition.secretStaging.targetName}' was available for ${definition.name}`); + } + + await page.locator('#secretTarget').selectOption(targetValue); + await fillById(page, '#secretBundleId', definition.secretStaging.bundleId); + await fillById(page, '#secretLogicalPath', definition.secretStaging.logicalPath); + + for (const [entryKey, entryValue] of Object.entries(definition.secretStaging.entries ?? {})) { + await fillById(page, `#secret-${entryKey}`, entryValue); + } +} + +async function resolveSecretTargetValue(page, targetName) { + const select = page.locator('#secretTarget'); + if (!(await select.isVisible().catch(() => false))) { + return null; + } + + const options = select.locator('option'); + const count = await options.count(); + for (let index = 0; index < count; index += 1) { + const option = options.nth(index); + const label = (await option.textContent().catch(() => '')).trim(); + const value = (await option.getAttribute('value').catch(() => null))?.trim(); + if (!value) { + continue; + } + + if (label.includes(targetName)) { + return value; + } + } + + return null; +} + +async function populateScope(page, definition) { + if (await page.locator('#repositories').isVisible().catch(() => false)) { + await fillById(page, '#repositories', (definition.repositories ?? []).join('\n')); + } + + if (await page.locator('#branches').isVisible().catch(() => false)) { + await fillById(page, '#branches', (definition.branches ?? []).join('\n')); + } + + if (await page.locator('#namespaces').isVisible().catch(() => false)) { + await fillById(page, '#namespaces', (definition.namespaces ?? []).join('\n')); + } + + if (await page.locator('#tagPatterns').isVisible().catch(() => false)) { + await fillById(page, '#tagPatterns', (definition.tagPatterns ?? []).join('\n')); + } + + const nextButton = await waitForNextEnabled(page); + await nextButton.click({ timeout: 10_000 }); + await page.getByRole('heading', { name: /Check Schedule/i }).waitFor({ timeout: 15_000 }); +} + +async function advanceToReview(page) { + let nextButton = await waitForNextEnabled(page); + await nextButton.click({ timeout: 10_000 }); + await page.getByRole('heading', { name: /Preflight Checks/i }).waitFor({ timeout: 15_000 }); + + nextButton = await waitForNextEnabled(page, 25_000); + await nextButton.click({ timeout: 10_000 }); + await page.getByRole('heading', { name: /Review & Create/i }).waitFor({ timeout: 15_000 }); +} + +async function createViaUi(page, definition) { + await page.goto(onboardingUrl(definition.route), { + waitUntil: 'domcontentloaded', + timeout: 30_000, + }); + await settle(page); + + await selectProviderIfNeeded(page, definition); + await populateConnection(page, definition); + await populateScope(page, definition); + await advanceToReview(page); + + await fillById(page, '#integrationName', definition.name); + await addTags(page, definition.tags); + + await page.getByRole('button', { name: /Create Integration/i }).click({ timeout: 10_000 }); + await page.waitForURL((url) => url.pathname.startsWith('/setup/integrations/') && !url.pathname.includes('/onboarding/'), { + timeout: 20_000, + }); + await settle(page); + + return new URL(page.url()).pathname.split('/').filter(Boolean).pop() ?? null; +} + +async function exerciseDetailActions(page) { + const actions = { + openedHealthTab: false, + ranTestConnection: false, + ranHealthCheck: false, + }; + + actions.openedHealthTab = await invokeUiButtonIfVisible(page, /^Health$/i); + if (actions.openedHealthTab) { + await settle(page, 500); + } + + actions.ranTestConnection = await invokeUiButtonIfVisible(page, /Test Connection/i); + if (actions.ranTestConnection) { + await page.getByRole('heading', { name: /Last Test Result/i }).waitFor({ timeout: 20_000 }).catch(() => {}); + await settle(page, 1_000); + } + + actions.ranHealthCheck = await invokeUiButtonIfVisible(page, /Check Health/i); + if (actions.ranHealthCheck) { + await page.getByRole('heading', { name: /Last Health Check/i }).waitFor({ timeout: 20_000 }).catch(() => {}); + await settle(page, 1_000); + } + + return actions; +} + +async function getVerification(apiContext, integrationId) { + const [testResponse, healthResponse] = await Promise.all([ + apiContext.post(`/api/v1/integrations/${integrationId}/test`), + apiContext.get(`/api/v1/integrations/${integrationId}/health`), + ]); + + let testBody = null; + let healthBody = null; + + try { + testBody = await testResponse.json(); + } catch { + testBody = await testResponse.text().catch(() => null); + } + + try { + healthBody = await healthResponse.json(); + } catch { + healthBody = await healthResponse.text().catch(() => null); + } + + return { + testStatusCode: testResponse.status(), + healthStatusCode: healthResponse.status(), + test: testBody, + health: healthBody, + }; +} + +async function deleteIntegrationViaUi(page, summary, item) { + await page.goto(integrationCredentialsUrl(item.id), { + waitUntil: 'domcontentloaded', + timeout: 30_000, + }); + await settle(page); + + const record = { + id: item.id, + name: item.name, + endpoint: item.endpoint, + provider: item.provider, + action: 'deleted', + snapshotBeforeDelete: await captureSnapshot(page, `${item.name}-pre-delete`), + }; + + page.once('dialog', (dialog) => dialog.accept().catch(() => {})); + await page.getByRole('button', { name: /Delete Integration/i }).click({ timeout: 10_000 }); + await page.waitForURL((url) => /^\/setup\/integrations\/?$/.test(url.pathname), { + timeout: 20_000, + }); + await settle(page, 750); + + record.snapshotAfterDelete = await captureSnapshot(page, `${item.name}-deleted`); + summary.deletedIntegrations.push(record); + await persistSummary(summary); +} + +async function ensureIntegration(page, apiContext, summary, definition) { + const existing = await findExistingIntegration(apiContext, definition); + let integrationId = existing?.id ?? null; + let action = 'existing'; + + if (!integrationId) { + integrationId = await createViaUi(page, definition); + action = 'created'; + } else { + await page.goto(integrationUrl(integrationId), { + waitUntil: 'domcontentloaded', + timeout: 30_000, + }); + await settle(page); + } + + if (!integrationId) { + throw new Error(`UI did not produce an integration id for ${definition.name}`); + } + + const detailActions = await exerciseDetailActions(page); + const verification = await getVerification(apiContext, integrationId); + + const result = { + name: definition.name, + route: definition.route, + provider: definition.provider, + endpoint: definition.endpoint, + action, + integrationId, + detailActions, + verification, + snapshot: await captureSnapshot(page, definition.name), + }; + + summary.integrations.push(result); + await persistSummary(summary); + return result; +} + +async function main() { + await mkdir(outputDir, { recursive: true }); + + const authReport = await authenticateFrontdoor({ + statePath: authStatePath, + reportPath: authReportPath, + headless, + }); + + const accessToken = getAccessToken(authReport); + if (!accessToken) { + throw new Error('Failed to extract frontdoor access token from authenticated session.'); + } + + const apiContext = await createApiContext(accessToken); + const browser = await chromium.launch({ + headless, + args: ['--disable-dev-shm-usage'], + }); + const context = await createAuthenticatedContext(browser, authReport, { statePath: authStatePath }); + const page = await context.newPage(); + + const summary = { + generatedAtUtc: new Date().toISOString(), + baseUrl, + scopeQuery, + includeGitLab, + gitLabStageSecrets, + resetExisting, + deletedIntegrations: [], + integrations: [], + runtime: { + consoleErrors: [], + pageErrors: [], + requestFailures: [], + responseErrors: [], + }, + }; + + page.on('console', (message) => { + if (message.type() === 'error') { + summary.runtime.consoleErrors.push({ page: page.url(), text: message.text() }); + } + }); + page.on('pageerror', (error) => { + summary.runtime.pageErrors.push({ page: page.url(), message: error.message }); + }); + page.on('requestfailed', (request) => { + const url = request.url(); + if (/\.(?:css|js|map|png|jpg|jpeg|svg|woff2?)(?:$|\?)/i.test(url)) { + return; + } + + summary.runtime.requestFailures.push({ + page: page.url(), + method: request.method(), + url, + error: request.failure()?.errorText ?? 'unknown', + }); + }); + page.on('response', (response) => { + const url = response.url(); + if (/\.(?:css|js|map|png|jpg|jpeg|svg|woff2?)(?:$|\?)/i.test(url)) { + return; + } + + if (response.status() >= 400) { + summary.runtime.responseErrors.push({ + page: page.url(), + method: response.request().method(), + status: response.status(), + url, + }); + } + }); + + try { + if (resetExisting) { + const existingItems = await listIntegrations(apiContext); + const managedItems = existingItems + .filter(matchesManagedDefinition) + .sort((left, right) => left.name.localeCompare(right.name)); + + for (const item of managedItems) { + try { + await deleteIntegrationViaUi(page, summary, item); + } catch (error) { + summary.deletedIntegrations.push({ + id: item.id, + name: item.name, + endpoint: item.endpoint, + provider: item.provider, + action: 'delete-failed', + error: error instanceof Error ? error.message : String(error), + snapshot: await captureSnapshot(page, `${item.name}-delete-failed`).catch(() => null), + }); + await persistSummary(summary); + } + } + } + + for (const definition of integrationDefinitions) { + try { + await ensureIntegration(page, apiContext, summary, definition); + } catch (error) { + summary.integrations.push({ + name: definition.name, + route: definition.route, + provider: definition.provider, + endpoint: definition.endpoint, + action: 'failed', + error: error instanceof Error ? error.message : String(error), + snapshot: await captureSnapshot(page, `${definition.name}-failed`).catch(() => null), + }); + await persistSummary(summary); + } + } + + const items = await listIntegrations(apiContext); + summary.finalCatalog = { + totalCount: items.length, + names: items.map((item) => item.name).sort((left, right) => left.localeCompare(right)), + }; + summary.failedResetCount = summary.deletedIntegrations.filter((entry) => entry.action === 'delete-failed').length; + summary.deletedIntegrationCount = summary.deletedIntegrations.filter((entry) => entry.action === 'deleted').length; + summary.failedIntegrationCount = summary.integrations.filter((entry) => entry.action === 'failed').length; + summary.healthyIntegrationCount = summary.integrations.filter((entry) => entry.verification?.health?.status === 1).length; + summary.successfulTestCount = summary.integrations.filter((entry) => entry.verification?.test?.success === true).length; + await persistSummary(summary); + } finally { + await apiContext.dispose().catch(() => {}); + await browser.close().catch(() => {}); + } + + process.stdout.write(`${JSON.stringify(summary, null, 2)}\n`); + if ((summary.failedIntegrationCount ?? 0) > 0 || (summary.failedResetCount ?? 0) > 0) { + process.exitCode = 1; + } +} + +main().catch((error) => { + process.stderr.write(`[live-integrations-ui-bootstrap] ${error instanceof Error ? error.message : String(error)}\n`); + process.exitCode = 1; +}); diff --git a/src/Web/StellaOps.Web/scripts/live-setup-wizard-full-bootstrap.mjs b/src/Web/StellaOps.Web/scripts/live-setup-wizard-full-bootstrap.mjs new file mode 100644 index 000000000..edf2521ea --- /dev/null +++ b/src/Web/StellaOps.Web/scripts/live-setup-wizard-full-bootstrap.mjs @@ -0,0 +1,569 @@ +#!/usr/bin/env node + +import { mkdir, writeFile } from 'node:fs/promises'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +import { chromium } from 'playwright'; + +import { authenticateFrontdoor, createAuthenticatedContext } from './live-frontdoor-auth.mjs'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const webRoot = path.resolve(__dirname, '..'); +const outputDir = path.join(webRoot, 'output', 'playwright'); +const outputPath = path.join(outputDir, 'live-setup-wizard-full-bootstrap.json'); +const authStatePath = path.join(outputDir, 'live-setup-wizard-full-bootstrap.state.json'); +const authReportPath = path.join(outputDir, 'live-setup-wizard-full-bootstrap.auth.json'); +const baseUrl = process.env.STELLAOPS_FRONTDOOR_BASE_URL?.trim() || 'https://stella-ops.local'; +const wizardUrl = `${baseUrl}/setup-wizard/wizard?mode=reconfigure`; +const headless = (process.env.STELLAOPS_UI_BOOTSTRAP_HEADLESS || 'true').toLowerCase() !== 'false'; + +function isStaticAsset(url) { + return /\.(?:css|js|map|png|jpg|jpeg|svg|woff2?|ico)(?:$|\?)/i.test(url); +} + +function createRuntime() { + return { + consoleErrors: [], + pageErrors: [], + requestFailures: [], + responseErrors: [], + }; +} + +function normalizeStepId(value) { + switch ((value ?? '').toString().trim().toLowerCase()) { + case 'database': + return 'database'; + case 'valkey': + case 'cache': + return 'cache'; + case 'migrations': + return 'migrations'; + case 'admin': + return 'admin'; + case 'crypto': + return 'crypto'; + default: + return (value ?? '').toString().trim().toLowerCase(); + } +} + +function normalizeStepStatus(value) { + switch ((value ?? '').toString().trim().toLowerCase()) { + case 'inprogress': + return 'in_progress'; + case 'pass': + case 'passed': + return 'completed'; + default: + return (value ?? '').toString().trim().toLowerCase(); + } +} + +function attachRuntime(page, runtime) { + page.on('console', (message) => { + if ( + message.type() === 'error' + && !message.text().startsWith('Failed to load resource: the server responded with a status of') + ) { + runtime.consoleErrors.push({ page: page.url(), text: message.text() }); + } + }); + + page.on('pageerror', (error) => { + if (page.url() === 'about:blank' && String(error).includes('sessionStorage')) { + return; + } + + runtime.pageErrors.push({ + page: page.url(), + text: error instanceof Error ? error.message : String(error), + }); + }); + + page.on('requestfailed', (request) => { + const errorText = request.failure()?.errorText ?? 'unknown'; + if ( + isStaticAsset(request.url()) + || errorText === 'net::ERR_ABORTED' + || (!request.url().includes('/api/v1/setup') && !request.url().includes('/setup-wizard')) + ) { + return; + } + + runtime.requestFailures.push({ + page: page.url(), + method: request.method(), + url: request.url(), + error: errorText, + }); + }); + + page.on('response', (response) => { + if ( + isStaticAsset(response.url()) + || response.url().includes('/api/v1/stella-assistant/tips') + || (!response.url().includes('/api/v1/setup') && !response.url().includes('/setup-wizard')) + ) { + return; + } + + if (response.status() >= 400) { + runtime.responseErrors.push({ + page: page.url(), + method: response.request().method(), + status: response.status(), + url: response.url(), + }); + } + }); +} + +function cleanText(value) { + return typeof value === 'string' ? value.replace(/\s+/g, ' ').trim() : ''; +} + +async function settle(page, ms = 1500) { + await page.waitForLoadState('domcontentloaded', { timeout: 20_000 }).catch(() => {}); + await page.waitForTimeout(ms); +} + +async function captureSnapshot(page, label) { + const alerts = await page + .locator('[role="alert"], .error-banner, .warning-banner, .banner, .toast, .notification, .status-card, .test-result') + .evaluateAll((nodes) => + nodes + .map((node) => (node.textContent || '').replace(/\s+/g, ' ').trim()) + .filter(Boolean) + .slice(0, 10), + ) + .catch(() => []); + + const visibleButtons = await page + .locator('button') + .evaluateAll((nodes) => + nodes + .map((node) => (node.textContent || '').replace(/\s+/g, ' ').trim()) + .filter(Boolean) + .slice(0, 12), + ) + .catch(() => []); + + return { + label, + url: page.url(), + title: await page.title().catch(() => ''), + heading: cleanText(await page.locator('h1, h2').first().textContent().catch(() => '')), + alerts, + visibleButtons, + }; +} + +async function readCurrentSession(page) { + const result = await page.evaluate(async () => { + const sessionPayload = + localStorage.getItem('stellaops.auth.session.full') + ?? sessionStorage.getItem('stellaops.auth.session.full'); + const accessToken = sessionPayload ? JSON.parse(sessionPayload)?.tokens?.accessToken ?? null : null; + const response = await fetch('/api/v1/setup/sessions/current', { + credentials: 'include', + headers: { + Accept: 'application/json', + ...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {}), + }, + }); + + const bodyText = await response.text(); + let body = null; + try { + body = JSON.parse(bodyText); + } catch { + body = null; + } + + return { + status: response.status, + ok: response.ok, + body, + bodyText: bodyText.slice(0, 4000), + }; + }); + + const session = result?.body?.session ?? null; + return { + status: result.status, + ok: result.ok, + sessionId: session?.sessionId ?? null, + currentStepId: normalizeStepId(session?.currentStepId ?? null), + sessionStatus: normalizeStepStatus(session?.status ?? null), + steps: Array.isArray(session?.steps) + ? session.steps.map((step) => ({ + stepId: normalizeStepId(step.stepId), + status: normalizeStepStatus(step.status), + lastProbeSucceeded: step.lastProbeSucceeded ?? null, + errorMessage: step.errorMessage ?? null, + })) + : [], + raw: result, + }; +} + +async function restartSetupSession(page) { + return page.evaluate(async () => { + const sessionPayload = + localStorage.getItem('stellaops.auth.session.full') + ?? sessionStorage.getItem('stellaops.auth.session.full'); + const accessToken = sessionPayload ? JSON.parse(sessionPayload)?.tokens?.accessToken ?? null : null; + const response = await fetch('/api/v1/setup/sessions', { + method: 'POST', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + ...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {}), + }, + body: JSON.stringify({ forceRestart: true }), + }); + + const bodyText = await response.text(); + let body = null; + try { + body = JSON.parse(bodyText); + } catch { + body = null; + } + + return { + status: response.status, + ok: response.ok, + body, + bodyText: bodyText.slice(0, 4000), + }; + }); +} + +async function waitForCurrentStep(page, expectedStepId) { + await page.waitForFunction( + async (stepId) => { + const sessionPayload = + localStorage.getItem('stellaops.auth.session.full') + ?? sessionStorage.getItem('stellaops.auth.session.full'); + const accessToken = sessionPayload ? JSON.parse(sessionPayload)?.tokens?.accessToken ?? null : null; + const response = await fetch('/api/v1/setup/sessions/current', { + credentials: 'include', + headers: { + Accept: 'application/json', + ...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {}), + }, + }); + + if (!response.ok) { + return false; + } + + const body = await response.json().catch(() => null); + return body?.session?.currentStepId === stepId; + }, + expectedStepId, + { timeout: 30_000 }, + ); + await page.waitForTimeout(1000); +} + +async function waitForSessionStatus(page, expectedStatus) { + await page.waitForFunction( + async (status) => { + const sessionPayload = + localStorage.getItem('stellaops.auth.session.full') + ?? sessionStorage.getItem('stellaops.auth.session.full'); + const accessToken = sessionPayload ? JSON.parse(sessionPayload)?.tokens?.accessToken ?? null : null; + const response = await fetch('/api/v1/setup/sessions/current', { + credentials: 'include', + headers: { + Accept: 'application/json', + ...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {}), + }, + }); + + if (!response.ok) { + return false; + } + + const body = await response.json().catch(() => null); + return (body?.session?.status || '').toString().toLowerCase() === status; + }, + expectedStatus, + { timeout: 30_000 }, + ); + await page.waitForTimeout(1000); +} + +async function fillIfVisible(page, selector, value) { + const locator = page.locator(selector); + if (!(await locator.isVisible().catch(() => false))) { + return false; + } + + await locator.fill(value); + await page.waitForTimeout(150); + return true; +} + +async function ensureFieldValue(page, selector, value) { + const locator = page.locator(selector); + if (!(await locator.isVisible().catch(() => false))) { + return false; + } + + const currentValue = await locator.inputValue().catch(() => ''); + if (cleanText(currentValue) === cleanText(value) && cleanText(currentValue) !== '') { + return true; + } + + if (cleanText(currentValue) === '') { + await locator.fill(value); + await page.waitForTimeout(150); + return true; + } + + await locator.fill(value); + await page.waitForTimeout(150); + return true; +} + +async function clickPrimaryAction(page, namePattern) { + const button = page.getByRole('button', { name: namePattern }).first(); + await button.click({ timeout: 10_000 }); +} + +async function applyStep(page, currentStepId, nextStepId) { + await Promise.all([ + page.waitForResponse( + (response) => + response.request().method() === 'POST' + && response.url().includes('/api/v1/setup/sessions/') + && response.url().includes(`/steps/${currentStepId}/apply`), + { timeout: 30_000 }, + ), + clickPrimaryAction(page, /^Apply and Continue$/), + ]); + + if (nextStepId) { + await waitForCurrentStep(page, nextStepId); + } else { + await waitForSessionStatus(page, 'completed'); + } +} + +async function validateDatabase(page) { + const validateButton = page.getByRole('button', { name: /^Validate Connection$/ }).first(); + if (!(await validateButton.isVisible().catch(() => false))) { + return false; + } + + await Promise.all([ + page.waitForResponse( + (response) => + response.request().method() === 'POST' + && response.url().includes('/api/v1/setup/sessions/') + && response.url().includes('/steps/database/probe'), + { timeout: 30_000 }, + ), + validateButton.click({ timeout: 10_000 }), + ]); + await settle(page, 1500); + return true; +} + +async function chooseDefaultCryptoProvider(page) { + const target = page.getByRole('button', { name: /Default \(Recommended\)/i }).first(); + if (!(await target.isVisible().catch(() => false))) { + return false; + } + + await target.click({ timeout: 10_000 }); + await page.waitForTimeout(300); + return true; +} + +async function main() { + await mkdir(outputDir, { recursive: true }); + + const authReport = await authenticateFrontdoor({ + statePath: authStatePath, + reportPath: authReportPath, + headless, + }); + + const browser = await chromium.launch({ + headless, + args: ['--ignore-certificate-errors', '--disable-dev-shm-usage'], + }); + + const context = await createAuthenticatedContext(browser, authReport, { + statePath: authStatePath, + }); + + const page = await context.newPage(); + const runtime = createRuntime(); + attachRuntime(page, runtime); + + const results = []; + + await page.goto(`${baseUrl}/welcome`, { waitUntil: 'domcontentloaded', timeout: 30_000 }); + await settle(page, 1000); + const forcedSession = await restartSetupSession(page); + + await page.goto(wizardUrl, { waitUntil: 'domcontentloaded', timeout: 30_000 }); + await settle(page, 2500); + await page.getByRole('button', { name: 'Start Setup', exact: true }).waitFor({ state: 'visible', timeout: 20_000 }); + + const welcomeSession = await readCurrentSession(page); + results.push({ + action: 'force-restart-to-welcome', + ok: forcedSession.ok && welcomeSession.currentStepId === 'database', + forcedSession, + session: welcomeSession, + snapshot: await captureSnapshot(page, 'welcome'), + }); + + await clickPrimaryAction(page, /^Start Setup$/); + await page.waitForFunction( + () => (document.body?.innerText || '').replace(/\s+/g, ' ').includes('PostgreSQL Connection'), + { timeout: 30_000 }, + ); + await settle(page, 1000); + + await ensureFieldValue(page, '#db-host', 'db.stella-ops.local'); + await ensureFieldValue(page, '#db-port', '5432'); + await ensureFieldValue(page, '#db-database', 'stellaops_platform'); + await ensureFieldValue(page, '#db-user', 'stellaops'); + await ensureFieldValue(page, '#db-password', 'stellaops'); + const databaseValidated = await validateDatabase(page); + await applyStep(page, 'database', 'cache'); + results.push({ + action: 'database-step-completed', + ok: (await readCurrentSession(page)).currentStepId === 'cache', + validated: databaseValidated, + session: await readCurrentSession(page), + snapshot: await captureSnapshot(page, 'database-complete'), + }); + + await page.waitForFunction( + () => (document.body?.innerText || '').replace(/\s+/g, ' ').includes('Valkey/Redis Connection'), + { timeout: 30_000 }, + ); + await settle(page, 750); + await ensureFieldValue(page, '#cache-host', 'cache.stella-ops.local'); + await ensureFieldValue(page, '#cache-port', '6379'); + await fillIfVisible(page, '#cache-password', ''); + await ensureFieldValue(page, '#cache-database', '0'); + await applyStep(page, 'cache', 'migrations'); + results.push({ + action: 'cache-step-completed', + ok: (await readCurrentSession(page)).currentStepId === 'migrations', + session: await readCurrentSession(page), + snapshot: await captureSnapshot(page, 'cache-complete'), + }); + + await page.waitForFunction( + () => (document.body?.innerText || '').replace(/\s+/g, ' ').includes('Database Migrations'), + { timeout: 30_000 }, + ); + await settle(page, 1000); + await applyStep(page, 'migrations', 'admin'); + results.push({ + action: 'migrations-step-completed', + ok: (await readCurrentSession(page)).currentStepId === 'admin', + session: await readCurrentSession(page), + snapshot: await captureSnapshot(page, 'migrations-complete'), + }); + + await page.waitForFunction( + () => (document.body?.innerText || '').replace(/\s+/g, ' ').includes('Super User Account'), + { timeout: 30_000 }, + ); + await settle(page, 750); + await ensureFieldValue(page, '#users-superuser-username', 'admin'); + await ensureFieldValue(page, '#users-superuser-email', 'admin@stella-ops.local'); + await ensureFieldValue(page, '#users-superuser-password', 'Admin@Stella1'); + await applyStep(page, 'admin', 'crypto'); + results.push({ + action: 'admin-step-completed', + ok: (await readCurrentSession(page)).currentStepId === 'crypto', + session: await readCurrentSession(page), + snapshot: await captureSnapshot(page, 'admin-complete'), + }); + + await page.waitForFunction( + () => (document.body?.innerText || '').replace(/\s+/g, ' ').includes('Cryptographic Provider'), + { timeout: 30_000 }, + ); + await settle(page, 750); + const cryptoSelected = await chooseDefaultCryptoProvider(page); + + await Promise.all([ + page.waitForResponse( + (response) => + response.request().method() === 'POST' + && response.url().includes('/api/v1/setup/sessions/') + && response.url().includes('/finalize'), + { timeout: 30_000 }, + ), + clickPrimaryAction(page, /^Finish Setup$/), + ]); + + await Promise.race([ + page.waitForURL((url) => !url.pathname.includes('/setup-wizard/wizard'), { timeout: 30_000 }), + waitForSessionStatus(page, 'completed'), + ]); + await settle(page, 1500); + + const finalSession = await readCurrentSession(page); + results.push({ + action: 'crypto-finalize-completed', + ok: cryptoSelected && finalSession.sessionStatus === 'completed', + cryptoSelected, + session: finalSession, + snapshot: await captureSnapshot(page, 'finalized'), + }); + + const runtimeIssueCount = + runtime.consoleErrors.length + + runtime.pageErrors.length + + runtime.requestFailures.length + + runtime.responseErrors.length; + const failedActionCount = results.filter((entry) => !entry.ok).length; + + const summary = { + generatedAtUtc: new Date().toISOString(), + failedActionCount, + runtimeIssueCount, + currentUrl: page.url(), + results, + finalSession, + runtime, + }; + + await writeFile(outputPath, `${JSON.stringify(summary, null, 2)}\n`, 'utf8'); + + await context.close(); + await browser.close(); + + if (failedActionCount > 0 || runtimeIssueCount > 0) { + process.exitCode = 1; + } +} + +main().catch(async (error) => { + await mkdir(outputDir, { recursive: true }); + const summary = { + generatedAtUtc: new Date().toISOString(), + fatalError: error instanceof Error ? error.message : String(error), + }; + await writeFile(outputPath, `${JSON.stringify(summary, null, 2)}\n`, 'utf8'); + console.error(error); + process.exitCode = 1; +}); diff --git a/src/Web/StellaOps.Web/scripts/live-setup-wizard-state-truth-check.mjs b/src/Web/StellaOps.Web/scripts/live-setup-wizard-state-truth-check.mjs new file mode 100644 index 000000000..814fcf337 --- /dev/null +++ b/src/Web/StellaOps.Web/scripts/live-setup-wizard-state-truth-check.mjs @@ -0,0 +1,452 @@ +#!/usr/bin/env node + +import { mkdir, writeFile } from 'node:fs/promises'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +import { chromium } from 'playwright'; + +import { authenticateFrontdoor, createAuthenticatedContext } from './live-frontdoor-auth.mjs'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const webRoot = path.resolve(__dirname, '..'); +const outputDir = path.join(webRoot, 'output', 'playwright'); +const outputPath = path.join(outputDir, 'live-setup-wizard-state-truth-check.json'); +const authStatePath = path.join(outputDir, 'live-setup-wizard-state-truth-check.state.json'); +const authReportPath = path.join(outputDir, 'live-setup-wizard-state-truth-check.auth.json'); +const baseUrl = process.env.STELLAOPS_FRONTDOOR_BASE_URL?.trim() || 'https://stella-ops.local'; +const wizardUrl = `${baseUrl}/setup-wizard/wizard?mode=reconfigure`; + +function isStaticAsset(url) { + return /\.(?:css|js|map|png|jpg|jpeg|svg|woff2?|ico)(?:$|\?)/i.test(url); +} + +function createRuntime() { + return { + consoleErrors: [], + pageErrors: [], + requestFailures: [], + responseErrors: [], + }; +} + +function normalizeStepId(value) { + switch ((value ?? '').toString().trim().toLowerCase()) { + case 'database': + return 'database'; + case 'valkey': + case 'cache': + return 'cache'; + case 'migrations': + return 'migrations'; + case 'admin': + return 'admin'; + case 'crypto': + return 'crypto'; + default: + return (value ?? '').toString().trim().toLowerCase(); + } +} + +function normalizeStepStatus(value) { + switch ((value ?? '').toString().trim().toLowerCase()) { + case 'inprogress': + return 'in_progress'; + case 'pass': + case 'passed': + return 'completed'; + default: + return (value ?? '').toString().trim().toLowerCase(); + } +} + +function attachRuntime(page, runtime) { + page.on('console', (message) => { + if ( + message.type() === 'error' + && !message.text().startsWith('Failed to load resource: the server responded with a status of') + ) { + runtime.consoleErrors.push({ page: page.url(), text: message.text() }); + } + }); + + page.on('pageerror', (error) => { + if (page.url() === 'about:blank' && String(error).includes('sessionStorage')) { + return; + } + + runtime.pageErrors.push({ + page: page.url(), + text: error instanceof Error ? error.message : String(error), + }); + }); + + page.on('requestfailed', (request) => { + const errorText = request.failure()?.errorText ?? 'unknown'; + if ( + isStaticAsset(request.url()) + || errorText === 'net::ERR_ABORTED' + || (!request.url().includes('/api/v1/setup') && !request.url().includes('/setup-wizard')) + ) { + return; + } + + runtime.requestFailures.push({ + page: page.url(), + method: request.method(), + url: request.url(), + error: errorText, + }); + }); + + page.on('response', (response) => { + if ( + isStaticAsset(response.url()) + || response.url().includes('/api/v1/stella-assistant/tips') + || (!response.url().includes('/api/v1/setup') && !response.url().includes('/setup-wizard')) + ) { + return; + } + + if (response.status() >= 400) { + runtime.responseErrors.push({ + page: page.url(), + method: response.request().method(), + status: response.status(), + url: response.url(), + }); + } + }); +} + +function cleanText(value) { + return typeof value === 'string' ? value.replace(/\s+/g, ' ').trim() : ''; +} + +async function settle(page, ms = 1500) { + await page.waitForLoadState('domcontentloaded', { timeout: 20_000 }).catch(() => {}); + await page.waitForTimeout(ms); +} + +async function captureSnapshot(page, label) { + const alerts = await page + .locator('[role="alert"], .error-banner, .warning-banner, .banner, .toast, .notification') + .evaluateAll((nodes) => + nodes + .map((node) => (node.textContent || '').replace(/\s+/g, ' ').trim()) + .filter(Boolean) + .slice(0, 8), + ) + .catch(() => []); + + const visibleButtons = await page + .locator('button') + .evaluateAll((nodes) => + nodes + .map((node) => (node.textContent || '').replace(/\s+/g, ' ').trim()) + .filter(Boolean) + .slice(0, 10), + ) + .catch(() => []); + + return { + label, + url: page.url(), + title: await page.title().catch(() => ''), + heading: cleanText(await page.locator('h1, h2').first().textContent().catch(() => '')), + alerts, + visibleButtons, + }; +} + +async function readCurrentSession(page) { + const result = await page.evaluate(async () => { + const sessionPayload = + localStorage.getItem('stellaops.auth.session.full') + ?? sessionStorage.getItem('stellaops.auth.session.full'); + const accessToken = sessionPayload ? JSON.parse(sessionPayload)?.tokens?.accessToken ?? null : null; + const response = await fetch('/api/v1/setup/sessions/current', { + credentials: 'include', + headers: { + Accept: 'application/json', + ...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {}), + }, + }); + + const bodyText = await response.text(); + let body = null; + try { + body = JSON.parse(bodyText); + } catch { + body = null; + } + + return { + status: response.status, + ok: response.ok, + body, + bodyText: bodyText.slice(0, 2000), + }; + }); + + const session = result?.body?.session ?? null; + return { + status: result.status, + ok: result.ok, + sessionId: session?.sessionId ?? null, + currentStepId: normalizeStepId(session?.currentStepId ?? null), + sessionStatus: normalizeStepStatus(session?.status ?? null), + steps: Array.isArray(session?.steps) + ? session.steps.map((step) => ({ + stepId: normalizeStepId(step.stepId), + status: normalizeStepStatus(step.status), + lastProbeSucceeded: step.lastProbeSucceeded ?? null, + errorMessage: step.errorMessage ?? null, + })) + : [], + raw: result, + }; +} + +function stepStatus(sessionSnapshot, stepId) { + return sessionSnapshot.steps.find((step) => step.stepId === stepId) ?? null; +} + +async function restartSetupSession(page) { + return page.evaluate(async () => { + const sessionPayload = + localStorage.getItem('stellaops.auth.session.full') + ?? sessionStorage.getItem('stellaops.auth.session.full'); + const accessToken = sessionPayload ? JSON.parse(sessionPayload)?.tokens?.accessToken ?? null : null; + const response = await fetch('/api/v1/setup/sessions', { + method: 'POST', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + ...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {}), + }, + body: JSON.stringify({ forceRestart: true }), + }); + + const bodyText = await response.text(); + let body = null; + try { + body = JSON.parse(bodyText); + } catch { + body = null; + } + + return { + status: response.status, + ok: response.ok, + body, + bodyText: bodyText.slice(0, 2000), + }; + }); +} + +async function waitForStep(page, markerText) { + await page.waitForFunction( + (marker) => (document.body?.innerText || '').includes(marker), + markerText, + { timeout: 30_000 }, + ); + await page.waitForTimeout(1000); +} + +async function waitForCurrentStep(page, expectedStepId) { + await page.waitForFunction( + async (stepId) => { + const sessionPayload = + localStorage.getItem('stellaops.auth.session.full') + ?? sessionStorage.getItem('stellaops.auth.session.full'); + const accessToken = sessionPayload ? JSON.parse(sessionPayload)?.tokens?.accessToken ?? null : null; + const response = await fetch('/api/v1/setup/sessions/current', { + credentials: 'include', + headers: { + Accept: 'application/json', + ...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {}), + }, + }); + + if (!response.ok) { + return false; + } + + const body = await response.json().catch(() => null); + return body?.session?.currentStepId === stepId; + }, + expectedStepId, + { timeout: 30_000 }, + ); + await page.waitForTimeout(1000); +} + +async function main() { + await mkdir(outputDir, { recursive: true }); + + const authReport = await authenticateFrontdoor({ + statePath: authStatePath, + reportPath: authReportPath, + }); + + const browser = await chromium.launch({ + headless: true, + args: ['--ignore-certificate-errors', '--disable-dev-shm-usage'], + }); + + const context = await createAuthenticatedContext(browser, authReport, { + statePath: authStatePath, + }); + + const page = await context.newPage(); + const runtime = createRuntime(); + attachRuntime(page, runtime); + + const results = []; + + await page.goto(`${baseUrl}/welcome`, { waitUntil: 'domcontentloaded', timeout: 30_000 }); + await settle(page, 1500); + const forcedSession = await restartSetupSession(page); + + await page.goto(wizardUrl, { waitUntil: 'domcontentloaded', timeout: 30_000 }); + await settle(page, 2500); + await page.getByRole('button', { name: 'Start Setup', exact: true }).waitFor({ state: 'visible', timeout: 20_000 }); + + const welcomeSession = await readCurrentSession(page); + const welcomeSnapshot = await captureSnapshot(page, 'welcome'); + results.push({ + action: 'welcome-route', + ok: page.url().includes('/setup-wizard/wizard') + && welcomeSnapshot.heading === 'Welcome to Stella Ops' + && welcomeSession.status === 200 + && welcomeSession.currentStepId === 'database' + && forcedSession.status === 201 + && forcedSession.body?.session?.sessionId === welcomeSession.sessionId, + snapshot: welcomeSnapshot, + session: welcomeSession, + forcedSession, + }); + + const startButton = page.getByRole('button', { name: 'Start Setup', exact: true }).first(); + await startButton.click({ timeout: 10_000 }); + await waitForStep(page, 'PostgreSQL Connection'); + + const databaseStepSnapshot = await captureSnapshot(page, 'database-step'); + const databaseBeforeProbe = await readCurrentSession(page); + results.push({ + action: 'start-setup', + ok: databaseStepSnapshot.visibleButtons.some((button) => button.includes('Validate Connection')) + && databaseStepSnapshot.visibleButtons.some((button) => button.includes('Apply and Continue')) + && databaseBeforeProbe.currentStepId === 'database', + snapshot: databaseStepSnapshot, + session: databaseBeforeProbe, + }); + + const validateButton = page.getByRole('button', { name: 'Validate Connection', exact: true }).first(); + await Promise.all([ + page.waitForResponse( + (response) => + response.request().method() === 'POST' + && response.url().includes('/api/v1/setup/sessions/') + && response.url().includes('/steps/database/probe'), + { timeout: 30_000 }, + ), + validateButton.click({ timeout: 10_000 }), + ]); + await settle(page, 2500); + + const afterProbeSession = await readCurrentSession(page); + const databaseAfterProbe = stepStatus(afterProbeSession, 'database'); + results.push({ + action: 'probe-does-not-complete-step', + ok: afterProbeSession.currentStepId === 'database' + && databaseAfterProbe?.status !== 'completed' + && databaseAfterProbe?.lastProbeSucceeded === true, + snapshot: await captureSnapshot(page, 'after-probe'), + session: afterProbeSession, + }); + + const applyButton = page.getByRole('button', { name: /Apply and Continue/i }).first(); + await Promise.all([ + page.waitForResponse( + (response) => + response.request().method() === 'POST' + && response.url().includes('/api/v1/setup/sessions/') + && response.url().includes('/steps/database/apply'), + { timeout: 30_000 }, + ), + applyButton.click({ timeout: 10_000 }), + ]); + await waitForCurrentStep(page, 'cache'); + await page.waitForFunction( + () => (document.body?.innerText || '').replace(/\s+/g, ' ').includes('Valkey/Redis'), + { timeout: 30_000 }, + ); + await page.waitForTimeout(1000); + + const afterApplySession = await readCurrentSession(page); + const databaseAfterApply = stepStatus(afterApplySession, 'database'); + results.push({ + action: 'apply-advances-backend-state', + ok: afterApplySession.currentStepId === 'cache' + && databaseAfterApply?.status === 'completed', + snapshot: await captureSnapshot(page, 'after-apply'), + session: afterApplySession, + }); + + await page.reload({ waitUntil: 'domcontentloaded', timeout: 30_000 }); + await waitForCurrentStep(page, 'cache'); + await page.waitForFunction( + () => (document.body?.innerText || '').replace(/\s+/g, ' ').includes('Valkey/Redis'), + { timeout: 30_000 }, + ); + await page.waitForTimeout(1000); + + const afterReloadSession = await readCurrentSession(page); + results.push({ + action: 'reload-preserves-session-state', + ok: afterReloadSession.sessionId === afterApplySession.sessionId + && afterReloadSession.currentStepId === 'cache' + && stepStatus(afterReloadSession, 'database')?.status === 'completed', + snapshot: await captureSnapshot(page, 'after-reload'), + session: afterReloadSession, + }); + + const runtimeIssueCount = + runtime.consoleErrors.length + + runtime.pageErrors.length + + runtime.requestFailures.length + + runtime.responseErrors.length; + const failedActionCount = results.filter((entry) => !entry.ok).length; + + const summary = { + generatedAtUtc: new Date().toISOString(), + failedActionCount, + runtimeIssueCount, + results, + runtime, + }; + + await writeFile(outputPath, `${JSON.stringify(summary, null, 2)}\n`, 'utf8'); + + await context.close(); + await browser.close(); + + if (failedActionCount > 0 || runtimeIssueCount > 0) { + process.exitCode = 1; + } +} + +main().catch(async (error) => { + await mkdir(outputDir, { recursive: true }); + const summary = { + generatedAtUtc: new Date().toISOString(), + fatalError: error instanceof Error ? error.message : String(error), + }; + await writeFile(outputPath, `${JSON.stringify(summary, null, 2)}\n`, 'utf8'); + console.error(error); + process.exitCode = 1; +}); diff --git a/src/Web/StellaOps.Web/src/app/app.config.ts b/src/Web/StellaOps.Web/src/app/app.config.ts index bfdbb3e52..cc913d63d 100644 --- a/src/Web/StellaOps.Web/src/app/app.config.ts +++ b/src/Web/StellaOps.Web/src/app/app.config.ts @@ -654,12 +654,7 @@ export const appConfig: ApplicationConfig = { deps: [AppConfigService], useFactory: (config: AppConfigService) => { const gatewayBase = config.config.apiBaseUrls.gateway ?? config.config.apiBaseUrls.authority; - try { - return new URL('/api/v1/release-jobengine', gatewayBase).toString(); - } catch { - const normalized = gatewayBase.endsWith('/') ? gatewayBase.slice(0, -1) : gatewayBase; - return `${normalized}/api/v1/release-orchestrator`; - } + return resolveApiBaseUrl(gatewayBase, '/api/v1/release-orchestrator'); }, }, ReleaseDashboardHttpClient, @@ -673,12 +668,7 @@ export const appConfig: ApplicationConfig = { deps: [AppConfigService], useFactory: (config: AppConfigService) => { const gatewayBase = config.config.apiBaseUrls.gateway ?? config.config.apiBaseUrls.authority; - try { - return new URL('/api/v1/release-jobengine', gatewayBase).toString(); - } catch { - const normalized = gatewayBase.endsWith('/') ? gatewayBase.slice(0, -1) : gatewayBase; - return `${normalized}/api/v1/release-orchestrator`; - } + return resolveApiBaseUrl(gatewayBase, '/api/v1/release-orchestrator'); }, }, ReleaseEnvironmentHttpClient, diff --git a/src/Web/StellaOps.Web/src/app/app.routes.ts b/src/Web/StellaOps.Web/src/app/app.routes.ts index 4221e9721..b4a7698c0 100644 --- a/src/Web/StellaOps.Web/src/app/app.routes.ts +++ b/src/Web/StellaOps.Web/src/app/app.routes.ts @@ -393,7 +393,7 @@ export const routes: Routes = [ redirectTo: preserveAppRedirect('/releases/promotions/:promotionId'), pathMatch: 'full', }, - { path: 'environments', redirectTo: preserveAppRedirect('/environments/overview'), pathMatch: 'full' }, + { path: 'environments', redirectTo: preserveAppRedirect('/releases/environments'), pathMatch: 'full' }, { path: 'regions', redirectTo: preserveAppRedirect('/environments/overview'), pathMatch: 'full' }, { path: 'setup', redirectTo: '/ops/platform-setup', pathMatch: 'full' }, { path: 'setup/environments-paths', redirectTo: '/environments/overview', pathMatch: 'full' }, diff --git a/src/Web/StellaOps.Web/src/app/core/api/release-dashboard.client.ts b/src/Web/StellaOps.Web/src/app/core/api/release-dashboard.client.ts index 5b3cb7408..c04e5b9e7 100644 --- a/src/Web/StellaOps.Web/src/app/core/api/release-dashboard.client.ts +++ b/src/Web/StellaOps.Web/src/app/core/api/release-dashboard.client.ts @@ -1,7 +1,6 @@ import { Injectable, InjectionToken, inject } from '@angular/core'; import { HttpClient } from '@angular/common/http'; -import { Observable, of, delay } from 'rxjs'; -import { AppConfigService } from '../config/app-config.service'; +import { Observable } from 'rxjs'; import type { DashboardData, PipelineData, PendingApproval, ActiveDeployment, RecentRelease } from './release-dashboard.models'; export const RELEASE_DASHBOARD_API_BASE_URL = new InjectionToken('RELEASE_DASHBOARD_API_BASE_URL'); @@ -31,113 +30,3 @@ export class ReleaseDashboardHttpClient implements ReleaseDashboardApi { return this.http.post(`${this.baseUrl}/promotions/${id}/reject`, { reason }); } } - -@Injectable({ providedIn: 'root' }) -export class MockReleaseDashboardClient implements ReleaseDashboardApi { - getDashboardData(): Observable { - const mockData: DashboardData = { - pipelineData: { - environments: [ - { id: 'dev', name: 'dev', displayName: 'Development', order: 1, releaseCount: 5, pendingCount: 0, healthStatus: 'healthy' }, - { id: 'staging', name: 'staging', displayName: 'Staging', order: 2, releaseCount: 3, pendingCount: 1, healthStatus: 'healthy' }, - { id: 'uat', name: 'uat', displayName: 'UAT', order: 3, releaseCount: 2, pendingCount: 0, healthStatus: 'degraded' }, - { id: 'prod', name: 'prod', displayName: 'Production', order: 4, releaseCount: 1, pendingCount: 2, healthStatus: 'healthy' }, - ], - connections: [ - { from: 'dev', to: 'staging' }, - { from: 'staging', to: 'uat' }, - { from: 'uat', to: 'prod' }, - ], - }, - pendingApprovals: [ - { - id: 'apr-001', - releaseId: 'rel-001', - releaseName: 'api-gateway', - releaseVersion: 'v2.3.1', - sourceEnvironment: 'Staging', - targetEnvironment: 'UAT', - requestedBy: 'john.doe@example.com', - requestedAt: new Date(Date.now() - 3600000).toISOString(), - urgency: 'normal', - }, - { - id: 'apr-002', - releaseId: 'rel-002', - releaseName: 'user-service', - releaseVersion: 'v1.5.0', - sourceEnvironment: 'UAT', - targetEnvironment: 'Production', - requestedBy: 'jane.smith@example.com', - requestedAt: new Date(Date.now() - 7200000).toISOString(), - urgency: 'high', - }, - ], - activeDeployments: [ - { - id: 'dep-001', - releaseId: 'rel-003', - releaseName: 'payment-service', - releaseVersion: 'v3.0.0', - environment: 'Staging', - progress: 75, - status: 'running', - startedAt: new Date(Date.now() - 180000).toISOString(), - completedTargets: 3, - totalTargets: 4, - }, - ], - recentReleases: [ - { - id: 'rel-001', - name: 'api-gateway', - version: 'v2.3.1', - status: 'promoting', - currentEnvironment: 'Staging', - createdAt: new Date(Date.now() - 86400000).toISOString(), - createdBy: 'john.doe@example.com', - componentCount: 3, - }, - { - id: 'rel-002', - name: 'user-service', - version: 'v1.5.0', - status: 'ready', - currentEnvironment: 'UAT', - createdAt: new Date(Date.now() - 172800000).toISOString(), - createdBy: 'jane.smith@example.com', - componentCount: 2, - }, - { - id: 'rel-003', - name: 'payment-service', - version: 'v3.0.0', - status: 'deployed', - currentEnvironment: 'Development', - createdAt: new Date(Date.now() - 259200000).toISOString(), - createdBy: 'bob.wilson@example.com', - componentCount: 4, - }, - { - id: 'rel-004', - name: 'notification-service', - version: 'v1.2.3', - status: 'deployed', - currentEnvironment: 'Production', - createdAt: new Date(Date.now() - 345600000).toISOString(), - createdBy: 'alice.johnson@example.com', - componentCount: 1, - }, - ], - }; - return of(mockData).pipe(delay(500)); - } - - approvePromotion(id: string): Observable { - return of(undefined).pipe(delay(300)); - } - - rejectPromotion(id: string, reason?: string): Observable { - return of(undefined).pipe(delay(300)); - } -} diff --git a/src/Web/StellaOps.Web/src/app/core/api/release-environment.client.ts b/src/Web/StellaOps.Web/src/app/core/api/release-environment.client.ts index 60be0ad4f..73abd5e18 100644 --- a/src/Web/StellaOps.Web/src/app/core/api/release-environment.client.ts +++ b/src/Web/StellaOps.Web/src/app/core/api/release-environment.client.ts @@ -1,40 +1,45 @@ import { Injectable, InjectionToken, inject } from '@angular/core'; import { HttpClient } from '@angular/common/http'; -import { Observable, of, delay } from 'rxjs'; +import { forkJoin, map, Observable, of, switchMap } from 'rxjs'; import type { + ComposeHostConnectionConfig, + CreateEnvironmentRequest, + CreateFreezeWindowRequest, + CreateTargetRequest, + DeploymentTarget, + DockerHostConnectionConfig, + EcsServiceConnectionConfig, Environment, EnvironmentListResponse, - CreateEnvironmentRequest, + FreezeRecurrence, + FreezeWindow, + NomadJobConnectionConfig, + SshHostConnectionConfig, + TargetConnectionConfig, + TargetHealthCheckResponse, + TargetInventorySnapshot, + TargetType, UpdateEnvironmentRequest, UpdateEnvironmentSettingsRequest, - DeploymentTarget, - CreateTargetRequest, - UpdateTargetRequest, - TargetHealthCheckResponse, - FreezeWindow, - CreateFreezeWindowRequest, UpdateFreezeWindowRequest, + UpdateTargetRequest, + WinRmHostConnectionConfig, } from './release-environment.models'; export const RELEASE_ENVIRONMENT_API_BASE_URL = new InjectionToken('RELEASE_ENVIRONMENT_API_BASE_URL'); export interface ReleaseEnvironmentApi { - // Environment CRUD listEnvironments(): Observable; getEnvironment(id: string): Observable; createEnvironment(request: CreateEnvironmentRequest): Observable; updateEnvironment(id: string, request: UpdateEnvironmentRequest): Observable; deleteEnvironment(id: string): Observable; updateEnvironmentSettings(id: string, settings: UpdateEnvironmentSettingsRequest): Observable; - - // Target management listTargets(environmentId: string): Observable; addTarget(environmentId: string, request: CreateTargetRequest): Observable; updateTarget(environmentId: string, targetId: string, request: UpdateTargetRequest): Observable; removeTarget(environmentId: string, targetId: string): Observable; checkTargetHealth(environmentId: string, targetId: string): Observable; - - // Freeze window management listFreezeWindows(environmentId: string): Observable; createFreezeWindow(environmentId: string, request: CreateFreezeWindowRequest): Observable; updateFreezeWindow(environmentId: string, windowId: string, request: UpdateFreezeWindowRequest): Observable; @@ -43,25 +48,131 @@ export interface ReleaseEnvironmentApi { export const RELEASE_ENVIRONMENT_API = new InjectionToken('RELEASE_ENVIRONMENT_API'); +interface BackendEnvironment { + id: string; + tenantId: string; + name: string; + displayName: string; + description?: string | null; + orderIndex: number; + isProduction: boolean; + requiredApprovals: number; + requireSeparationOfDuties: boolean; + autoPromoteFrom?: string | null; + deploymentTimeoutSeconds: number; + createdAt: string; + updatedAt: string; + createdBy: string; +} + +interface BackendTarget { + id: string; + tenantId: string; + environmentId: string; + name: string; + displayName: string; + type: string; + connectionConfig: Record; + agentId?: string | null; + healthStatus: string; + healthMessage?: string | null; + lastHealthCheck?: string | null; + lastSyncAt?: string | null; + inventorySnapshot?: BackendInventorySnapshot | null; + createdAt: string; + updatedAt: string; +} + +interface BackendInventorySnapshot { + takenAt: string; + containers: Array<{ + containerId: string; + name: string; + image: string; + digest?: string | null; + status: string; + createdAt?: string | null; + labels?: Record | null; + }>; +} + +interface BackendFreezeWindow { + id: string; + environmentId: string; + name: string; + startAt: string; + endAt: string; + reason?: string | null; + isRecurring: boolean; + recurrenceRule?: string | null; + isActive: boolean; + createdAt: string; + createdBy: string; +} + +interface BackendConnectionTestResult { + success: boolean; + message?: string | null; + duration: string; + testedAt: string; +} + @Injectable({ providedIn: 'root' }) export class ReleaseEnvironmentHttpClient implements ReleaseEnvironmentApi { private readonly http = inject(HttpClient); private readonly baseUrl = inject(RELEASE_ENVIRONMENT_API_BASE_URL); listEnvironments(): Observable { - return this.http.get(`${this.baseUrl}/environments`); + return this.http.get(`${this.baseUrl}/environments`).pipe( + switchMap((items) => { + if (items.length === 0) { + return of({ items: [], totalCount: 0 }); + } + + return forkJoin(items.map((item) => this.enrichEnvironment(item))).pipe( + map((environments) => ({ + items: environments, + totalCount: environments.length, + })) + ); + }) + ); } getEnvironment(id: string): Observable { - return this.http.get(`${this.baseUrl}/environments/${id}`); + return this.http.get(`${this.baseUrl}/environments/${id}`).pipe( + switchMap((environment) => this.enrichEnvironment(environment)) + ); } createEnvironment(request: CreateEnvironmentRequest): Observable { - return this.http.post(`${this.baseUrl}/environments`, request); + return this.http.post( + `${this.baseUrl}/environments`, + { + name: request.name, + displayName: request.displayName, + description: request.description || null, + orderIndex: Math.max((request.order || 1) - 1, 0), + isProduction: request.isProduction, + requiredApprovals: request.requiresApproval ? request.requiredApprovers : 0, + requireSeparationOfDuties: request.separationOfDuties ?? false, + deploymentTimeoutSeconds: request.deploymentTimeout ?? 1800, + }).pipe( + switchMap((environment) => this.enrichEnvironment(environment)) + ); } updateEnvironment(id: string, request: UpdateEnvironmentRequest): Observable { - return this.http.put(`${this.baseUrl}/environments/${id}`, request); + return this.http.put( + `${this.baseUrl}/environments/${id}`, + { + displayName: request.displayName, + description: request.description, + orderIndex: request.order === undefined ? undefined : Math.max(request.order - 1, 0), + isProduction: request.isProduction, + }).pipe( + switchMap((environment) => this.enrichEnvironment(environment)) + ); } deleteEnvironment(id: string): Observable { @@ -69,576 +180,433 @@ export class ReleaseEnvironmentHttpClient implements ReleaseEnvironmentApi { } updateEnvironmentSettings(id: string, settings: UpdateEnvironmentSettingsRequest): Observable { - return this.http.put(`${this.baseUrl}/environments/${id}/settings`, settings); + return this.http.put( + `${this.baseUrl}/environments/${id}/settings`, + { + requiredApprovals: settings.requiresApproval ? settings.requiredApprovers : 0, + requireSeparationOfDuties: settings.separationOfDuties, + deploymentTimeoutSeconds: settings.deploymentTimeout, + }).pipe( + switchMap((environment) => this.enrichEnvironment(environment)) + ); } listTargets(environmentId: string): Observable { - return this.http.get(`${this.baseUrl}/environments/${environmentId}/targets`); + return this.http + .get(`${this.baseUrl}/environments/${environmentId}/targets`) + .pipe(map((targets) => targets.map((target) => mapTarget(target)))); } addTarget(environmentId: string, request: CreateTargetRequest): Observable { - return this.http.post(`${this.baseUrl}/environments/${environmentId}/targets`, request); + return this.http.post( + `${this.baseUrl}/environments/${environmentId}/targets`, + { + name: request.name, + displayName: request.displayName, + type: toBackendTargetType(request.type), + connectionConfig: request.connectionConfig, + agentId: normalizeGuid(request.agentId), + }).pipe( + map((target) => mapTarget(target)) + ); } - updateTarget(environmentId: string, targetId: string, request: UpdateTargetRequest): Observable { - return this.http.put(`${this.baseUrl}/environments/${environmentId}/targets/${targetId}`, request); + updateTarget(_environmentId: string, targetId: string, request: UpdateTargetRequest): Observable { + return this.http.put( + `${this.baseUrl}/targets/${targetId}`, + { + displayName: request.displayName, + connectionConfig: request.connectionConfig, + agentId: request.agentId === undefined ? undefined : normalizeGuid(request.agentId), + }).pipe( + map((target) => mapTarget(target)) + ); } - removeTarget(environmentId: string, targetId: string): Observable { - return this.http.delete(`${this.baseUrl}/environments/${environmentId}/targets/${targetId}`); + removeTarget(_environmentId: string, targetId: string): Observable { + return this.http.delete(`${this.baseUrl}/targets/${targetId}`); } - checkTargetHealth(environmentId: string, targetId: string): Observable { - return this.http.post( - `${this.baseUrl}/environments/${environmentId}/targets/${targetId}/health-check`, - {} - ); + checkTargetHealth(_environmentId: string, targetId: string): Observable { + return this.http + .post(`${this.baseUrl}/targets/${targetId}/health-check`, {}) + .pipe( + map((result) => ({ + success: result.success, + message: result.message ?? undefined, + duration: result.duration, + checkedAt: result.testedAt, + healthStatus: result.success ? 'healthy' : 'unreachable', + })) + ); } listFreezeWindows(environmentId: string): Observable { - return this.http.get(`${this.baseUrl}/environments/${environmentId}/freeze-windows`); + return this.http + .get(`${this.baseUrl}/environments/${environmentId}/freeze-windows`) + .pipe(map((windows) => windows.map((window) => mapFreezeWindow(window)))); } createFreezeWindow(environmentId: string, request: CreateFreezeWindowRequest): Observable { - return this.http.post(`${this.baseUrl}/environments/${environmentId}/freeze-windows`, request); + const recurrence = toBackendRecurrence(request.recurrence); + + return this.http.post( + `${this.baseUrl}/environments/${environmentId}/freeze-windows`, + { + name: request.name, + reason: request.reason || null, + startAt: request.startTime, + endAt: request.endTime, + isRecurring: recurrence.isRecurring, + recurrenceRule: recurrence.recurrenceRule, + }).pipe( + map((window) => mapFreezeWindow(window)) + ); } - updateFreezeWindow(environmentId: string, windowId: string, request: UpdateFreezeWindowRequest): Observable { - return this.http.put( - `${this.baseUrl}/environments/${environmentId}/freeze-windows/${windowId}`, - request + updateFreezeWindow(_environmentId: string, windowId: string, request: UpdateFreezeWindowRequest): Observable { + const recurrence = request.recurrence === undefined + ? undefined + : toBackendRecurrence(request.recurrence); + + return this.http.put( + `${this.baseUrl}/freeze-windows/${windowId}`, + { + name: request.name, + reason: request.reason, + startAt: request.startTime, + endAt: request.endTime, + isRecurring: recurrence?.isRecurring, + recurrenceRule: recurrence?.recurrenceRule, + }).pipe( + map((window) => mapFreezeWindow(window)) + ); + } + + deleteFreezeWindow(_environmentId: string, windowId: string): Observable { + return this.http.delete(`${this.baseUrl}/freeze-windows/${windowId}`); + } + + private enrichEnvironment(environment: BackendEnvironment): Observable { + return forkJoin({ + targets: this.http.get(`${this.baseUrl}/environments/${environment.id}/targets`), + freezeWindows: this.http.get(`${this.baseUrl}/environments/${environment.id}/freeze-windows`), + }).pipe( + map(({ targets, freezeWindows }) => mapEnvironment(environment, targets, freezeWindows)) ); } +} - deleteFreezeWindow(environmentId: string, windowId: string): Observable { - return this.http.delete(`${this.baseUrl}/environments/${environmentId}/freeze-windows/${windowId}`); +function mapEnvironment( + environment: BackendEnvironment, + targets: BackendTarget[], + freezeWindows: BackendFreezeWindow[] +): Environment { + const healthyTargetCount = targets.filter((target) => normalizeHealthStatus(target.healthStatus) === 'healthy').length; + const hasActiveFreeze = freezeWindows.some((window) => { + if (window.isActive) { + return true; + } + + const now = Date.now(); + return Date.parse(window.startAt) <= now && now <= Date.parse(window.endAt); + }); + + return { + id: environment.id, + name: environment.name, + displayName: environment.displayName, + description: environment.description ?? '', + order: environment.orderIndex + 1, + isProduction: environment.isProduction, + targetCount: targets.length, + healthyTargetCount, + requiresApproval: environment.requiredApprovals > 0, + requiredApprovers: environment.requiredApprovals, + freezeWindowCount: freezeWindows.length, + activeFreezeWindow: hasActiveFreeze, + separationOfDuties: environment.requireSeparationOfDuties, + deploymentTimeout: environment.deploymentTimeoutSeconds, + autoPromoteSourceEnvironmentId: environment.autoPromoteFrom ?? undefined, + createdAt: environment.createdAt, + createdBy: environment.createdBy, + updatedAt: environment.updatedAt, + }; +} + +function mapTarget(target: BackendTarget): DeploymentTarget { + return { + id: target.id, + environmentId: target.environmentId, + name: target.name, + displayName: target.displayName, + type: normalizeTargetType(target.type), + connectionConfig: mapConnectionConfig(target.connectionConfig, target.type), + agentId: target.agentId ?? undefined, + healthStatus: normalizeHealthStatus(target.healthStatus), + healthMessage: target.healthMessage ?? undefined, + lastHealthCheck: target.lastHealthCheck ?? undefined, + lastSyncAt: target.lastSyncAt ?? undefined, + inventorySnapshot: mapInventorySnapshot(target.inventorySnapshot), + createdAt: target.createdAt, + updatedAt: target.updatedAt, + }; +} + +function mapInventorySnapshot(snapshot?: BackendInventorySnapshot | null): TargetInventorySnapshot | undefined { + if (!snapshot) { + return undefined; + } + + return { + takenAt: snapshot.takenAt, + containers: snapshot.containers.map((container) => ({ + containerId: container.containerId, + name: container.name, + image: container.image, + digest: container.digest ?? undefined, + status: container.status, + createdAt: container.createdAt ?? undefined, + labels: container.labels ?? undefined, + })), + }; +} + +function mapFreezeWindow(window: BackendFreezeWindow): FreezeWindow { + return { + id: window.id, + environmentId: window.environmentId, + name: window.name, + reason: window.reason ?? '', + startTime: window.startAt, + endTime: window.endAt, + recurrence: fromBackendRecurrence(window.isRecurring, window.recurrenceRule), + isActive: window.isActive, + createdBy: window.createdBy, + createdAt: window.createdAt, + }; +} + +function mapConnectionConfig(config: Record, type: string): TargetConnectionConfig { + const normalizedType = normalizeTargetType(type); + + switch (normalizedType) { + case 'docker_host': + return { + type: 'docker_host', + host: readString(config, 'host'), + port: readNumber(config, 'port', 2376), + useTls: readBoolean(config, 'useTls', true), + caCertSecretRef: readOptionalString(config, 'caCertSecretRef'), + clientCertSecretRef: readOptionalString(config, 'clientCertSecretRef'), + clientKeySecretRef: readOptionalString(config, 'clientKeySecretRef'), + } satisfies DockerHostConnectionConfig; + case 'compose_host': + return { + type: 'compose_host', + host: readString(config, 'host'), + port: readNumber(config, 'port', 2376), + useTls: readBoolean(config, 'useTls', true), + composeProjectPath: readString(config, 'composeProjectPath'), + composeFile: readString(config, 'composeFile', 'docker-compose.yml'), + caCertSecretRef: readOptionalString(config, 'caCertSecretRef'), + clientCertSecretRef: readOptionalString(config, 'clientCertSecretRef'), + clientKeySecretRef: readOptionalString(config, 'clientKeySecretRef'), + } satisfies ComposeHostConnectionConfig; + case 'ecs_service': + return { + type: 'ecs_service', + region: readString(config, 'region'), + clusterArn: readString(config, 'clusterArn'), + serviceName: readString(config, 'serviceName'), + roleArn: readOptionalString(config, 'roleArn'), + accessKeyIdSecretRef: readOptionalString(config, 'accessKeyIdSecretRef'), + secretAccessKeySecretRef: readOptionalString(config, 'secretAccessKeySecretRef'), + } satisfies EcsServiceConnectionConfig; + case 'nomad_job': + return { + type: 'nomad_job', + address: readString(config, 'address'), + namespace: readString(config, 'namespace'), + jobId: readString(config, 'jobId'), + tokenSecretRef: readOptionalString(config, 'tokenSecretRef'), + useTls: readBoolean(config, 'useTls', true), + } satisfies NomadJobConnectionConfig; + case 'ssh_host': + return { + type: 'ssh_host', + host: readString(config, 'host'), + port: readNumber(config, 'port', 22), + username: readString(config, 'username'), + privateKeySecretRef: readOptionalString(config, 'privateKeySecretRef'), + passwordSecretRef: readOptionalString(config, 'passwordSecretRef'), + knownHostsPolicy: normalizeKnownHostsPolicy(readOptionalString(config, 'knownHostsPolicy')), + } satisfies SshHostConnectionConfig; + case 'winrm_host': + default: + return { + type: 'winrm_host', + host: readString(config, 'host'), + port: readNumber(config, 'port', 5985), + transport: normalizeWinRmTransport(readOptionalString(config, 'transport')), + username: readString(config, 'username'), + passwordSecretRef: readOptionalString(config, 'passwordSecretRef'), + domain: readOptionalString(config, 'domain'), + } satisfies WinRmHostConnectionConfig; } } -@Injectable({ providedIn: 'root' }) -export class MockReleaseEnvironmentClient implements ReleaseEnvironmentApi { - private environments: Environment[] = [ - { - id: 'dev', - name: 'dev', - displayName: 'Development', - description: 'Development environment for testing new features', - order: 1, - isProduction: false, - targetCount: 2, - healthyTargetCount: 2, - requiresApproval: false, - requiredApprovers: 0, - freezeWindowCount: 0, - activeFreezeWindow: false, - autoPromoteOnSuccess: true, - separationOfDuties: false, - notifyOnPromotion: false, - notifyOnDeployment: true, - notifyOnFailure: true, - maxConcurrentDeployments: 5, - deploymentTimeout: 1800, - createdAt: new Date(Date.now() - 30 * 86400000).toISOString(), - createdBy: 'admin@example.com', - }, - { - id: 'staging', - name: 'staging', - displayName: 'Staging', - description: 'Pre-production testing environment', - order: 2, - isProduction: false, - targetCount: 3, - healthyTargetCount: 3, - requiresApproval: true, - requiredApprovers: 1, - freezeWindowCount: 1, - activeFreezeWindow: false, - autoPromoteOnSuccess: false, - separationOfDuties: false, - notifyOnPromotion: true, - notifyOnDeployment: true, - notifyOnFailure: true, - maxConcurrentDeployments: 3, - deploymentTimeout: 2400, - createdAt: new Date(Date.now() - 30 * 86400000).toISOString(), - createdBy: 'admin@example.com', - }, - { - id: 'uat', - name: 'uat', - displayName: 'UAT', - description: 'User acceptance testing environment', - order: 3, - isProduction: false, - targetCount: 2, - healthyTargetCount: 1, - requiresApproval: true, - requiredApprovers: 1, - freezeWindowCount: 0, - activeFreezeWindow: false, - autoPromoteOnSuccess: false, - separationOfDuties: true, - notifyOnPromotion: true, - notifyOnDeployment: true, - notifyOnFailure: true, - maxConcurrentDeployments: 2, - deploymentTimeout: 3600, - createdAt: new Date(Date.now() - 30 * 86400000).toISOString(), - createdBy: 'admin@example.com', - }, - { - id: 'prod', - name: 'prod', - displayName: 'Production', - description: 'Live production environment', - order: 4, - isProduction: true, - targetCount: 4, - healthyTargetCount: 4, - requiresApproval: true, - requiredApprovers: 2, - freezeWindowCount: 2, - activeFreezeWindow: false, - autoPromoteOnSuccess: false, - separationOfDuties: true, - notifyOnPromotion: true, - notifyOnDeployment: true, - notifyOnFailure: true, - webhookUrl: 'https://hooks.example.com/deployments', - maxConcurrentDeployments: 1, - deploymentTimeout: 7200, - createdAt: new Date(Date.now() - 30 * 86400000).toISOString(), - createdBy: 'admin@example.com', - }, - ]; +function readString(source: Record, key: string, fallback = ''): string { + const value = source[key]; + return typeof value === 'string' ? value : fallback; +} - private targets: Record = { - dev: [ - { - id: 'dev-web-01', - environmentId: 'dev', - name: 'dev-web-01', - type: 'docker_host', - agentId: 'agent-dev-01', - agentStatus: 'connected', - healthStatus: 'healthy', - lastHealthCheck: new Date(Date.now() - 300000).toISOString(), - metadata: { region: 'us-east-1' }, - createdAt: new Date(Date.now() - 30 * 86400000).toISOString(), - createdBy: 'admin@example.com', - }, - { - id: 'dev-api-01', - environmentId: 'dev', - name: 'dev-api-01', - type: 'docker_host', - agentId: 'agent-dev-01', - agentStatus: 'connected', - healthStatus: 'healthy', - lastHealthCheck: new Date(Date.now() - 300000).toISOString(), - metadata: { region: 'us-east-1' }, - createdAt: new Date(Date.now() - 30 * 86400000).toISOString(), - createdBy: 'admin@example.com', - }, - ], - staging: [ - { - id: 'stg-web-01', - environmentId: 'staging', - name: 'stg-web-01', - type: 'compose_host', - agentId: 'agent-stg-01', - agentStatus: 'connected', - healthStatus: 'healthy', - lastHealthCheck: new Date(Date.now() - 600000).toISOString(), - metadata: { region: 'us-east-1' }, - createdAt: new Date(Date.now() - 25 * 86400000).toISOString(), - createdBy: 'admin@example.com', - }, - { - id: 'stg-api-01', - environmentId: 'staging', - name: 'stg-api-01', - type: 'compose_host', - agentId: 'agent-stg-01', - agentStatus: 'connected', - healthStatus: 'healthy', - lastHealthCheck: new Date(Date.now() - 600000).toISOString(), - metadata: { region: 'us-east-1' }, - createdAt: new Date(Date.now() - 25 * 86400000).toISOString(), - createdBy: 'admin@example.com', - }, - { - id: 'stg-worker-01', - environmentId: 'staging', - name: 'stg-worker-01', - type: 'docker_host', - agentId: 'agent-stg-02', - agentStatus: 'connected', - healthStatus: 'healthy', - lastHealthCheck: new Date(Date.now() - 600000).toISOString(), - metadata: { region: 'us-east-1' }, - createdAt: new Date(Date.now() - 25 * 86400000).toISOString(), - createdBy: 'admin@example.com', - }, - ], - uat: [ - { - id: 'uat-web-01', - environmentId: 'uat', - name: 'uat-web-01', - type: 'ecs_service', - agentId: undefined, - agentStatus: 'unknown', - healthStatus: 'healthy', - lastHealthCheck: new Date(Date.now() - 900000).toISOString(), - metadata: { cluster: 'uat-cluster', service: 'web' }, - createdAt: new Date(Date.now() - 20 * 86400000).toISOString(), - createdBy: 'admin@example.com', - }, - { - id: 'uat-api-01', - environmentId: 'uat', - name: 'uat-api-01', - type: 'ecs_service', - agentId: undefined, - agentStatus: 'unknown', - healthStatus: 'unhealthy', - lastHealthCheck: new Date(Date.now() - 900000).toISOString(), - metadata: { cluster: 'uat-cluster', service: 'api' }, - createdAt: new Date(Date.now() - 20 * 86400000).toISOString(), - createdBy: 'admin@example.com', - }, - ], - prod: [ - { - id: 'prod-web-01', - environmentId: 'prod', - name: 'prod-web-01', - type: 'docker_host', - agentId: 'agent-prod-01', - agentStatus: 'connected', - healthStatus: 'healthy', - lastHealthCheck: new Date(Date.now() - 120000).toISOString(), - metadata: { region: 'us-east-1', az: 'us-east-1a' }, - createdAt: new Date(Date.now() - 60 * 86400000).toISOString(), - createdBy: 'admin@example.com', - }, - { - id: 'prod-web-02', - environmentId: 'prod', - name: 'prod-web-02', - type: 'docker_host', - agentId: 'agent-prod-02', - agentStatus: 'connected', - healthStatus: 'healthy', - lastHealthCheck: new Date(Date.now() - 120000).toISOString(), - metadata: { region: 'us-east-1', az: 'us-east-1b' }, - createdAt: new Date(Date.now() - 60 * 86400000).toISOString(), - createdBy: 'admin@example.com', - }, - { - id: 'prod-api-01', - environmentId: 'prod', - name: 'prod-api-01', - type: 'docker_host', - agentId: 'agent-prod-01', - agentStatus: 'connected', - healthStatus: 'healthy', - lastHealthCheck: new Date(Date.now() - 120000).toISOString(), - metadata: { region: 'us-east-1', az: 'us-east-1a' }, - createdAt: new Date(Date.now() - 60 * 86400000).toISOString(), - createdBy: 'admin@example.com', - }, - { - id: 'prod-api-02', - environmentId: 'prod', - name: 'prod-api-02', - type: 'docker_host', - agentId: 'agent-prod-02', - agentStatus: 'connected', - healthStatus: 'healthy', - lastHealthCheck: new Date(Date.now() - 120000).toISOString(), - metadata: { region: 'us-east-1', az: 'us-east-1b' }, - createdAt: new Date(Date.now() - 60 * 86400000).toISOString(), - createdBy: 'admin@example.com', - }, - ], - }; +function readOptionalString(source: Record, key: string): string | undefined { + const value = source[key]; + return typeof value === 'string' && value.length > 0 ? value : undefined; +} - private freezeWindows: Record = { - staging: [ - { - id: 'fw-stg-01', - environmentId: 'staging', - name: 'Weekend Freeze', - reason: 'No deployments during weekends', - startTime: '2026-01-17T18:00:00Z', - endTime: '2026-01-19T06:00:00Z', - recurrence: 'weekly', - isActive: false, - createdBy: 'admin@example.com', - createdAt: new Date(Date.now() - 14 * 86400000).toISOString(), - }, - ], - prod: [ - { - id: 'fw-prod-01', - environmentId: 'prod', - name: 'Holiday Freeze', - reason: 'No deployments during holidays', - startTime: '2026-01-01T00:00:00Z', - endTime: '2026-01-02T23:59:59Z', - recurrence: 'none', - isActive: false, - createdBy: 'admin@example.com', - createdAt: new Date(Date.now() - 30 * 86400000).toISOString(), - }, - { - id: 'fw-prod-02', - environmentId: 'prod', - name: 'Friday Lockdown', - reason: 'No deployments after Friday 4PM', - startTime: '2026-01-17T16:00:00Z', - endTime: '2026-01-20T08:00:00Z', - recurrence: 'weekly', - isActive: false, - createdBy: 'ops@example.com', - createdAt: new Date(Date.now() - 20 * 86400000).toISOString(), - }, - ], - }; +function readNumber(source: Record, key: string, fallback: number): number { + const value = source[key]; + return typeof value === 'number' ? value : fallback; +} - listEnvironments(): Observable { - return of({ - items: [...this.environments].sort((a, b) => a.order - b.order), - totalCount: this.environments.length, - }).pipe(delay(300)); - } +function readBoolean(source: Record, key: string, fallback: boolean): boolean { + const value = source[key]; + return typeof value === 'boolean' ? value : fallback; +} - getEnvironment(id: string): Observable { - const env = this.environments.find((e) => e.id === id); - if (!env) { - throw new Error(`Environment ${id} not found`); - } - return of(env).pipe(delay(200)); - } - - createEnvironment(request: CreateEnvironmentRequest): Observable { - const newEnv: Environment = { - id: request.name.toLowerCase().replace(/\s+/g, '-'), - ...request, - targetCount: 0, - healthyTargetCount: 0, - freezeWindowCount: 0, - activeFreezeWindow: false, - autoPromoteOnSuccess: false, - separationOfDuties: false, - notifyOnPromotion: true, - notifyOnDeployment: true, - notifyOnFailure: true, - maxConcurrentDeployments: 1, - deploymentTimeout: 3600, - createdAt: new Date().toISOString(), - createdBy: 'current-user@example.com', - }; - this.environments.push(newEnv); - this.targets[newEnv.id] = []; - this.freezeWindows[newEnv.id] = []; - return of(newEnv).pipe(delay(300)); - } - - updateEnvironment(id: string, request: UpdateEnvironmentRequest): Observable { - const idx = this.environments.findIndex((e) => e.id === id); - if (idx === -1) { - throw new Error(`Environment ${id} not found`); - } - this.environments[idx] = { - ...this.environments[idx], - ...request, - updatedAt: new Date().toISOString(), - updatedBy: 'current-user@example.com', - }; - return of(this.environments[idx]).pipe(delay(300)); - } - - deleteEnvironment(id: string): Observable { - const idx = this.environments.findIndex((e) => e.id === id); - if (idx === -1) { - throw new Error(`Environment ${id} not found`); - } - this.environments.splice(idx, 1); - delete this.targets[id]; - delete this.freezeWindows[id]; - return of(undefined).pipe(delay(300)); - } - - updateEnvironmentSettings(id: string, settings: UpdateEnvironmentSettingsRequest): Observable { - const idx = this.environments.findIndex((e) => e.id === id); - if (idx === -1) { - throw new Error(`Environment ${id} not found`); - } - this.environments[idx] = { - ...this.environments[idx], - ...settings, - updatedAt: new Date().toISOString(), - updatedBy: 'current-user@example.com', - }; - return of(this.environments[idx]).pipe(delay(300)); - } - - listTargets(environmentId: string): Observable { - return of(this.targets[environmentId] ?? []).pipe(delay(200)); - } - - addTarget(environmentId: string, request: CreateTargetRequest): Observable { - const newTarget: DeploymentTarget = { - id: `${environmentId}-${request.name}`, - environmentId, - name: request.name, - type: request.type, - agentId: request.agentId, - agentStatus: request.agentId ? 'connected' : 'unknown', - healthStatus: 'unknown', - metadata: request.metadata ?? {}, - createdAt: new Date().toISOString(), - createdBy: 'current-user@example.com', - }; - if (!this.targets[environmentId]) { - this.targets[environmentId] = []; - } - this.targets[environmentId].push(newTarget); - - // Update environment target count - const env = this.environments.find((e) => e.id === environmentId); - if (env) { - env.targetCount++; - } - - return of(newTarget).pipe(delay(300)); - } - - updateTarget(environmentId: string, targetId: string, request: UpdateTargetRequest): Observable { - const targets = this.targets[environmentId]; - if (!targets) { - throw new Error(`Environment ${environmentId} not found`); - } - const idx = targets.findIndex((t) => t.id === targetId); - if (idx === -1) { - throw new Error(`Target ${targetId} not found`); - } - targets[idx] = { - ...targets[idx], - ...request, - updatedAt: new Date().toISOString(), - }; - return of(targets[idx]).pipe(delay(300)); - } - - removeTarget(environmentId: string, targetId: string): Observable { - const targets = this.targets[environmentId]; - if (!targets) { - throw new Error(`Environment ${environmentId} not found`); - } - const idx = targets.findIndex((t) => t.id === targetId); - if (idx === -1) { - throw new Error(`Target ${targetId} not found`); - } - targets.splice(idx, 1); - - // Update environment target count - const env = this.environments.find((e) => e.id === environmentId); - if (env) { - env.targetCount--; - } - - return of(undefined).pipe(delay(300)); - } - - checkTargetHealth(environmentId: string, targetId: string): Observable { - const targets = this.targets[environmentId]; - if (!targets) { - throw new Error(`Environment ${environmentId} not found`); - } - const target = targets.find((t) => t.id === targetId); - if (!target) { - throw new Error(`Target ${targetId} not found`); - } - - // Update target health - target.healthStatus = 'healthy'; - target.lastHealthCheck = new Date().toISOString(); - - return of({ - targetId, - healthStatus: 'healthy' as const, - checkedAt: new Date().toISOString(), - details: { latencyMs: Math.floor(Math.random() * 50) + 10 }, - }).pipe(delay(500)); - } - - listFreezeWindows(environmentId: string): Observable { - return of(this.freezeWindows[environmentId] ?? []).pipe(delay(200)); - } - - createFreezeWindow(environmentId: string, request: CreateFreezeWindowRequest): Observable { - const newWindow: FreezeWindow = { - id: `fw-${environmentId}-${Date.now()}`, - environmentId, - ...request, - isActive: false, - createdBy: 'current-user@example.com', - createdAt: new Date().toISOString(), - }; - if (!this.freezeWindows[environmentId]) { - this.freezeWindows[environmentId] = []; - } - this.freezeWindows[environmentId].push(newWindow); - - // Update environment freeze window count - const env = this.environments.find((e) => e.id === environmentId); - if (env) { - env.freezeWindowCount++; - } - - return of(newWindow).pipe(delay(300)); - } - - updateFreezeWindow(environmentId: string, windowId: string, request: UpdateFreezeWindowRequest): Observable { - const windows = this.freezeWindows[environmentId]; - if (!windows) { - throw new Error(`Environment ${environmentId} not found`); - } - const idx = windows.findIndex((w) => w.id === windowId); - if (idx === -1) { - throw new Error(`Freeze window ${windowId} not found`); - } - windows[idx] = { - ...windows[idx], - ...request, - updatedAt: new Date().toISOString(), - }; - return of(windows[idx]).pipe(delay(300)); - } - - deleteFreezeWindow(environmentId: string, windowId: string): Observable { - const windows = this.freezeWindows[environmentId]; - if (!windows) { - throw new Error(`Environment ${environmentId} not found`); - } - const idx = windows.findIndex((w) => w.id === windowId); - if (idx === -1) { - throw new Error(`Freeze window ${windowId} not found`); - } - windows.splice(idx, 1); - - // Update environment freeze window count - const env = this.environments.find((e) => e.id === environmentId); - if (env) { - env.freezeWindowCount--; - } - - return of(undefined).pipe(delay(300)); +function normalizeTargetType(type: unknown): TargetType { + switch (type) { + case 0: + case 'DockerHost': + case 'dockerHost': + case 'docker_host': + return 'docker_host'; + case 1: + case 'ComposeHost': + case 'composeHost': + case 'compose_host': + return 'compose_host'; + case 2: + case 'EcsService': + case 'ecsService': + case 'ecs_service': + return 'ecs_service'; + case 3: + case 'NomadJob': + case 'nomadJob': + case 'nomad_job': + return 'nomad_job'; + case 4: + case 'SshHost': + case 'sshHost': + case 'ssh_host': + return 'ssh_host'; + case 5: + case 'WinRmHost': + case 'winRmHost': + case 'winrmHost': + case 'winrm_host': + return 'winrm_host'; + default: + return 'docker_host'; } } + +function toBackendTargetType(type: TargetType): string { + switch (type) { + case 'docker_host': + return 'dockerHost'; + case 'compose_host': + return 'composeHost'; + case 'ecs_service': + return 'ecsService'; + case 'nomad_job': + return 'nomadJob'; + case 'ssh_host': + return 'sshHost'; + case 'winrm_host': + return 'winRmHost'; + default: + return 'dockerHost'; + } +} + +function normalizeHealthStatus(status: unknown): DeploymentTarget['healthStatus'] { + switch (status) { + case 1: + case 'healthy': + case 'Healthy': + return 'healthy'; + case 2: + case 'degraded': + case 'Degraded': + return 'degraded'; + case 3: + case 'unhealthy': + case 'Unhealthy': + return 'unhealthy'; + case 4: + case 'unreachable': + case 'Unreachable': + return 'unreachable'; + case 0: + case 'unknown': + case 'Unknown': + default: + return 'unknown'; + } +} + +function normalizeKnownHostsPolicy(policy?: unknown): SshHostConnectionConfig['knownHostsPolicy'] { + switch (policy) { + case 1: + case 'strict': + case 'Strict': + return 'strict'; + case 2: + case 'prompt': + case 'Prompt': + return 'prompt'; + default: + return 'accept'; + } +} + +function normalizeWinRmTransport(transport?: unknown): WinRmHostConnectionConfig['transport'] { + return transport === 1 || transport === 'https' || transport === 'Https' ? 'https' : 'http'; +} + +function fromBackendRecurrence(isRecurring: boolean, recurrenceRule?: string | null): FreezeRecurrence { + if (!isRecurring || !recurrenceRule) { + return 'none'; + } + + const normalized = recurrenceRule.toUpperCase(); + if (normalized.includes('FREQ=DAILY')) { + return 'daily'; + } + if (normalized.includes('FREQ=MONTHLY')) { + return 'monthly'; + } + return 'weekly'; +} + +function toBackendRecurrence(recurrence: FreezeRecurrence): { isRecurring: boolean; recurrenceRule?: string } { + switch (recurrence) { + case 'daily': + return { isRecurring: true, recurrenceRule: 'FREQ=DAILY' }; + case 'weekly': + return { isRecurring: true, recurrenceRule: 'FREQ=WEEKLY' }; + case 'monthly': + return { isRecurring: true, recurrenceRule: 'FREQ=MONTHLY' }; + case 'none': + default: + return { isRecurring: false }; + } +} + +function normalizeGuid(value?: string): string | undefined { + return value && value.trim().length > 0 ? value.trim() : undefined; +} diff --git a/src/Web/StellaOps.Web/src/app/core/api/release-environment.models.ts b/src/Web/StellaOps.Web/src/app/core/api/release-environment.models.ts index 037a09313..55c36a4b7 100644 --- a/src/Web/StellaOps.Web/src/app/core/api/release-environment.models.ts +++ b/src/Web/StellaOps.Web/src/app/core/api/release-environment.models.ts @@ -1,9 +1,8 @@ /** * Release Environment Models - * Sprint: SPRINT_20260110_111_002_FE_environment_management_ui + * Backed by the real Release Orchestrator environment API. */ -// Environment entity export interface Environment { id: string; name: string; @@ -17,45 +16,132 @@ export interface Environment { requiredApprovers: number; freezeWindowCount: number; activeFreezeWindow: boolean; - autoPromoteOnSuccess: boolean; separationOfDuties: boolean; - notifyOnPromotion: boolean; - notifyOnDeployment: boolean; - notifyOnFailure: boolean; - webhookUrl?: string; - maxConcurrentDeployments: number; deploymentTimeout: number; + autoPromoteSourceEnvironmentId?: string; createdAt: string; createdBy: string; updatedAt?: string; - updatedBy?: string; } -// Deployment target types -export type TargetType = 'docker_host' | 'compose_host' | 'ecs_service' | 'nomad_job'; -export type AgentStatus = 'connected' | 'disconnected' | 'unknown'; -export type HealthStatus = 'healthy' | 'unhealthy' | 'unknown'; +export type TargetType = + | 'docker_host' + | 'compose_host' + | 'ecs_service' + | 'nomad_job' + | 'ssh_host' + | 'winrm_host'; + +export type HealthStatus = + | 'healthy' + | 'degraded' + | 'unhealthy' + | 'unreachable' + | 'unknown'; + +export interface TargetInventorySnapshot { + takenAt: string; + containers: TargetInventoryContainer[]; +} + +export interface TargetInventoryContainer { + containerId: string; + name: string; + image: string; + digest?: string; + status: string; + createdAt?: string; + labels?: Record; +} + +export interface DockerHostConnectionConfig { + type: 'docker_host'; + host: string; + port: number; + useTls: boolean; + caCertSecretRef?: string; + clientCertSecretRef?: string; + clientKeySecretRef?: string; +} + +export interface ComposeHostConnectionConfig { + type: 'compose_host'; + host: string; + port: number; + useTls: boolean; + composeProjectPath: string; + composeFile: string; + caCertSecretRef?: string; + clientCertSecretRef?: string; + clientKeySecretRef?: string; +} + +export interface EcsServiceConnectionConfig { + type: 'ecs_service'; + region: string; + clusterArn: string; + serviceName: string; + roleArn?: string; + accessKeyIdSecretRef?: string; + secretAccessKeySecretRef?: string; +} + +export interface NomadJobConnectionConfig { + type: 'nomad_job'; + address: string; + namespace: string; + jobId: string; + tokenSecretRef?: string; + useTls: boolean; +} + +export interface SshHostConnectionConfig { + type: 'ssh_host'; + host: string; + port: number; + username: string; + privateKeySecretRef?: string; + passwordSecretRef?: string; + knownHostsPolicy: 'accept' | 'strict' | 'prompt'; +} + +export interface WinRmHostConnectionConfig { + type: 'winrm_host'; + host: string; + port: number; + transport: 'http' | 'https'; + username: string; + passwordSecretRef?: string; + domain?: string; +} + +export type TargetConnectionConfig = + | DockerHostConnectionConfig + | ComposeHostConnectionConfig + | EcsServiceConnectionConfig + | NomadJobConnectionConfig + | SshHostConnectionConfig + | WinRmHostConnectionConfig; -// Deployment target export interface DeploymentTarget { id: string; environmentId: string; name: string; + displayName: string; type: TargetType; + connectionConfig: TargetConnectionConfig; agentId?: string; - agentStatus: AgentStatus; healthStatus: HealthStatus; + healthMessage?: string; lastHealthCheck?: string; - metadata: Record; + lastSyncAt?: string; + inventorySnapshot?: TargetInventorySnapshot; createdAt: string; - createdBy: string; updatedAt?: string; } -// Freeze window recurrence export type FreezeRecurrence = 'none' | 'daily' | 'weekly' | 'monthly'; -// Freeze window export interface FreezeWindow { id: string; environmentId: string; @@ -67,10 +153,8 @@ export interface FreezeWindow { isActive: boolean; createdBy: string; createdAt: string; - updatedAt?: string; } -// API request/response types export interface EnvironmentListResponse { items: Environment[]; totalCount: number; @@ -84,6 +168,8 @@ export interface CreateEnvironmentRequest { isProduction: boolean; requiresApproval: boolean; requiredApprovers: number; + separationOfDuties?: boolean; + deploymentTimeout?: number; } export interface UpdateEnvironmentRequest { @@ -96,34 +182,30 @@ export interface UpdateEnvironmentRequest { export interface UpdateEnvironmentSettingsRequest { requiresApproval: boolean; requiredApprovers: number; - autoPromoteOnSuccess: boolean; separationOfDuties: boolean; - notifyOnPromotion: boolean; - notifyOnDeployment: boolean; - notifyOnFailure: boolean; - webhookUrl?: string; - maxConcurrentDeployments: number; deploymentTimeout: number; } export interface CreateTargetRequest { name: string; + displayName: string; type: TargetType; + connectionConfig: TargetConnectionConfig; agentId?: string; - metadata?: Record; } export interface UpdateTargetRequest { - name?: string; + displayName?: string; + connectionConfig?: TargetConnectionConfig; agentId?: string; - metadata?: Record; } export interface TargetHealthCheckResponse { - targetId: string; - healthStatus: HealthStatus; + success: boolean; + message?: string; + duration: string; checkedAt: string; - details?: Record; + healthStatus: HealthStatus; } export interface CreateFreezeWindowRequest { @@ -142,7 +224,6 @@ export interface UpdateFreezeWindowRequest { recurrence?: FreezeRecurrence; } -// Display helpers export function getTargetTypeLabel(type: TargetType): string { switch (type) { case 'docker_host': @@ -153,6 +234,10 @@ export function getTargetTypeLabel(type: TargetType): string { return 'ECS Service'; case 'nomad_job': return 'Nomad Job'; + case 'ssh_host': + return 'SSH Host'; + case 'winrm_host': + return 'WinRM Host'; default: return 'Unknown'; } @@ -168,6 +253,10 @@ export function getTargetTypeIcon(type: TargetType): string { return 'pi-cloud'; case 'nomad_job': return 'pi-sitemap'; + case 'ssh_host': + return 'pi-desktop'; + case 'winrm_host': + return 'pi-microsoft'; default: return 'pi-server'; } @@ -177,23 +266,12 @@ export function getHealthStatusColor(status: HealthStatus): string { switch (status) { case 'healthy': return 'success'; + case 'degraded': + return 'warning'; case 'unhealthy': + case 'unreachable': return 'danger'; case 'unknown': - return 'secondary'; - default: - return 'secondary'; - } -} - -export function getAgentStatusColor(status: AgentStatus): string { - switch (status) { - case 'connected': - return 'success'; - case 'disconnected': - return 'danger'; - case 'unknown': - return 'secondary'; default: return 'secondary'; } diff --git a/src/Web/StellaOps.Web/src/app/core/auth/auth-session.store.spec.ts b/src/Web/StellaOps.Web/src/app/core/auth/auth-session.store.spec.ts index 154b6f4d1..4848d8656 100644 --- a/src/Web/StellaOps.Web/src/app/core/auth/auth-session.store.spec.ts +++ b/src/Web/StellaOps.Web/src/app/core/auth/auth-session.store.spec.ts @@ -48,6 +48,7 @@ describe('AuthSessionStore', () => { beforeEach(() => { sessionStorage.clear(); + localStorage.clear(); store = createStore(); }); @@ -56,17 +57,19 @@ describe('AuthSessionStore', () => { store.setSession(session); - const persisted = sessionStorage.getItem(SESSION_STORAGE_KEY); + const persisted = localStorage.getItem(SESSION_STORAGE_KEY); expect(persisted).toBeTruthy(); const parsed = JSON.parse(persisted ?? '{}'); expect(parsed.subject).toBe('user-123'); expect(parsed.dpopKeyThumbprint).toBe('thumbprint-1'); expect(parsed.tenantId).toBe('tenant-default'); expect(sessionStorage.getItem(FULL_SESSION_STORAGE_KEY)).toBeTruthy(); + expect(localStorage.getItem(FULL_SESSION_STORAGE_KEY)).toBeTruthy(); store.clear(); - expect(sessionStorage.getItem(SESSION_STORAGE_KEY)).toBeNull(); + expect(localStorage.getItem(SESSION_STORAGE_KEY)).toBeNull(); expect(sessionStorage.getItem(FULL_SESSION_STORAGE_KEY)).toBeNull(); + expect(localStorage.getItem(FULL_SESSION_STORAGE_KEY)).toBeNull(); }); it('rehydrates authenticated session from full session storage', () => { @@ -83,7 +86,7 @@ describe('AuthSessionStore', () => { it('drops expired persisted full session and sets expired status', () => { const expired = createSession(Date.now() - 5_000); sessionStorage.setItem(FULL_SESSION_STORAGE_KEY, JSON.stringify(expired)); - sessionStorage.setItem( + localStorage.setItem( SESSION_STORAGE_KEY, JSON.stringify({ subject: expired.identity.subject, diff --git a/src/Web/StellaOps.Web/src/app/features/deployments/deployments.routes.ts b/src/Web/StellaOps.Web/src/app/features/deployments/deployments.routes.ts index ff5f651c7..5f7b474f7 100644 --- a/src/Web/StellaOps.Web/src/app/features/deployments/deployments.routes.ts +++ b/src/Web/StellaOps.Web/src/app/features/deployments/deployments.routes.ts @@ -9,13 +9,17 @@ export const DEPLOYMENTS_ROUTES: Routes = [ { path: '', loadComponent: () => - import('./deployments-list-page.component').then(m => m.DeploymentsListPageComponent), + import('../release-orchestrator/deployments/deployment-list/deployment-list.component').then( + (m) => m.DeploymentListComponent, + ), data: { breadcrumb: 'Deployments' }, }, { - path: ':deploymentId', + path: ':id', loadComponent: () => - import('./deployment-detail-page.component').then(m => m.DeploymentDetailPageComponent), + import('../release-orchestrator/deployments/deployment-monitor/deployment-monitor.component').then( + (m) => m.DeploymentMonitorComponent, + ), data: { breadcrumb: 'Deployment Detail' }, }, ]; diff --git a/src/Web/StellaOps.Web/src/app/features/integration-hub/integration.models.ts b/src/Web/StellaOps.Web/src/app/features/integration-hub/integration.models.ts index 2cd7c7e6f..e052dbc23 100644 --- a/src/Web/StellaOps.Web/src/app/features/integration-hub/integration.models.ts +++ b/src/Web/StellaOps.Web/src/app/features/integration-hub/integration.models.ts @@ -126,6 +126,42 @@ export interface UpdateIntegrationRequest { status?: IntegrationStatus | null; } +export interface SecretAuthorityTarget { + integrationId: string; + name: string; + provider: IntegrationProvider; + endpoint: string; + status: string; + logicalPathHint: string; + supportsWrite: boolean; +} + +export interface SecretAuthorityTargetsResponse { + items: SecretAuthorityTarget[]; +} + +export interface SecretBundleEntryRequest { + key: string; + value: string; +} + +export interface UpsertSecretBundleRequest { + targetIntegrationId: string; + logicalPath?: string | null; + entries: SecretBundleEntryRequest[]; + labels?: Record | null; + overwrite?: boolean; +} + +export interface UpsertSecretBundleResponse { + targetIntegrationId: string; + bundleId: string; + logicalPath: string; + authRefs: Record; + provider: IntegrationProvider; + endpoint: string; +} + export interface TestConnectionResponse { integrationId: string; success: boolean; diff --git a/src/Web/StellaOps.Web/src/app/features/integration-hub/integration.service.spec.ts b/src/Web/StellaOps.Web/src/app/features/integration-hub/integration.service.spec.ts index 617d74dbd..87482889f 100644 --- a/src/Web/StellaOps.Web/src/app/features/integration-hub/integration.service.spec.ts +++ b/src/Web/StellaOps.Web/src/app/features/integration-hub/integration.service.spec.ts @@ -65,7 +65,7 @@ describe('IntegrationService', () => { organizationId: 'platform', extendedConfig: { namespaces: ['platform'] }, tags: ['prod'], - } as const; + }; service.create(request).subscribe((integration) => { expect(integration.id).toBe('int-1'); @@ -111,4 +111,62 @@ describe('IntegrationService', () => { { name: 'github-app', type: IntegrationType.Scm, provider: IntegrationProvider.GitHubApp }, ]); }); + + it('lists secret-authority targets from the integrations service', () => { + service.listSecretAuthorityTargets().subscribe((response) => { + expect(response.items).toEqual([ + jasmine.objectContaining({ + integrationId: 'vault-1', + name: 'Local Vault', + provider: IntegrationProvider.Vault, + status: 'healthy', + }), + ]); + }); + + const req = httpMock.expectOne('/api/v1/secret-authority/targets'); + expect(req.request.method).toBe('GET'); + req.flush({ + items: [ + { + integrationId: 'vault-1', + name: 'Local Vault', + provider: IntegrationProvider.Vault, + endpoint: 'http://vault.stella-ops.local:8200', + status: 'healthy', + logicalPathHint: 'local-vault', + supportsWrite: true, + }, + ], + }); + }); + + it('upserts secret bundles through the secret-authority endpoint', () => { + const request = { + targetIntegrationId: 'vault-1', + logicalPath: 'gitlab/server', + overwrite: true, + labels: { provider: '201' }, + entries: [{ key: 'access-token', value: 'glpat-123' }], + }; + + service.upsertSecretBundle('gitlab-server', request).subscribe((response) => { + expect(response.bundleId).toBe('gitlab-server'); + expect(response.authRefs['access-token']).toBe('authref://vault/gitlab/server#access-token'); + }); + + const req = httpMock.expectOne('/api/v1/secret-authority/bundles/gitlab-server'); + expect(req.request.method).toBe('PUT'); + expect(req.request.body).toEqual(request); + req.flush({ + targetIntegrationId: 'vault-1', + bundleId: 'gitlab-server', + logicalPath: 'gitlab/server', + authRefs: { + 'access-token': 'authref://vault/gitlab/server#access-token', + }, + provider: IntegrationProvider.Vault, + endpoint: 'http://vault.stella-ops.local:8200', + }); + }); }); diff --git a/src/Web/StellaOps.Web/src/app/features/integration-hub/integration.service.ts b/src/Web/StellaOps.Web/src/app/features/integration-hub/integration.service.ts index 1ca7fa928..fb739a369 100644 --- a/src/Web/StellaOps.Web/src/app/features/integration-hub/integration.service.ts +++ b/src/Web/StellaOps.Web/src/app/features/integration-hub/integration.service.ts @@ -10,8 +10,11 @@ import { IntegrationProvider, IntegrationStatus, IntegrationType, + SecretAuthorityTargetsResponse, SupportedProviderInfo, TestConnectionResponse, + UpsertSecretBundleRequest, + UpsertSecretBundleResponse, UpdateIntegrationRequest, } from './integration.models'; @@ -21,6 +24,7 @@ import { export class IntegrationService { private readonly http = inject(HttpClient); private readonly baseUrl = `${environment.apiBaseUrl}/v1/integrations`; + private readonly secretAuthorityBaseUrl = `${environment.apiBaseUrl}/v1/secret-authority`; list(params: { type?: IntegrationType; @@ -89,4 +93,12 @@ export class IntegrationService { getSupportedProviders(): Observable { return this.http.get(`${this.baseUrl}/providers`); } + + listSecretAuthorityTargets(): Observable { + return this.http.get(`${this.secretAuthorityBaseUrl}/targets`); + } + + upsertSecretBundle(bundleId: string, request: UpsertSecretBundleRequest): Observable { + return this.http.put(`${this.secretAuthorityBaseUrl}/bundles/${encodeURIComponent(bundleId)}`, request); + } } diff --git a/src/Web/StellaOps.Web/src/app/features/integrations/integration-wizard.component.html b/src/Web/StellaOps.Web/src/app/features/integrations/integration-wizard.component.html index 381f5801e..4db536697 100644 --- a/src/Web/StellaOps.Web/src/app/features/integrations/integration-wizard.component.html +++ b/src/Web/StellaOps.Web/src/app/features/integrations/integration-wizard.component.html @@ -97,6 +97,117 @@ {{ provider.authRefHint }} + @if (secretAuthorityProfile(); as secretProfile) { +
+ + {{ secretProfile.description }} + Manual `authref://...` values still work if credentials were staged elsewhere. + + @if (draft().secretBundle.enabled) { + @if (!hasHealthySecretTargets()) { +
+ !! +
+ No healthy secret-authority targets + + {{ + secretTargetsError() + || 'Create or recover a healthy Vault integration before using inline secret staging.' + }} + +
+
+ } @else { +
+
+ + + Only healthy, writable secrets-manager integrations are offered for inline staging. +
+ +
+ + + The bundle ID is used for audit and idempotent updates. +
+ +
+ + + Leave blank to reuse the bundle ID as the Vault logical path. +
+ + @for (field of secretProfile.entryFields; track field.id) { +
+ + + @if (field.hint) { + {{ field.hint }} + } +
+ } + + +
+ } + } +
+ } + @if (provider.organizationLabel) {
@@ -330,12 +441,22 @@

AuthRef URI

-

{{ draft().authRefUri }}

+

{{ getResolvedAuthRefPreview() }}

Schedule

{{ draft().schedule.type | titlecase }}

+ @if (draft().secretBundle.enabled) { +
+

Secret Bundle

+

{{ draft().secretBundle.logicalPath || draft().secretBundle.bundleId }}

+
+
+

Secret Target

+

{{ getSelectedSecretTargetName() || 'Not selected' }}

+
+ } } diff --git a/src/Web/StellaOps.Web/src/app/features/integrations/integration-wizard.component.scss b/src/Web/StellaOps.Web/src/app/features/integrations/integration-wizard.component.scss index 59d29dc21..200bd43b3 100644 --- a/src/Web/StellaOps.Web/src/app/features/integrations/integration-wizard.component.scss +++ b/src/Web/StellaOps.Web/src/app/features/integrations/integration-wizard.component.scss @@ -184,6 +184,20 @@ } } +.secret-authority-card { + margin-bottom: var(--space-4); + padding: var(--space-4); + background: var(--color-surface-tertiary); + border: 1px solid var(--color-border-primary); + border-radius: var(--radius-md); +} + +.secret-authority-fields { + margin-top: var(--space-4); + display: grid; + gap: var(--space-3); +} + .form-field { margin-bottom: var(--space-4); @@ -205,6 +219,14 @@ } } +.toggle-label { + display: flex; + align-items: flex-start; + gap: var(--space-2); + cursor: pointer; + font-weight: var(--font-weight-medium); +} + .schedule-options { display: flex; flex-direction: column; diff --git a/src/Web/StellaOps.Web/src/app/features/integrations/integration-wizard.component.spec.ts b/src/Web/StellaOps.Web/src/app/features/integrations/integration-wizard.component.spec.ts index ba708be9c..1a111a58a 100644 --- a/src/Web/StellaOps.Web/src/app/features/integrations/integration-wizard.component.spec.ts +++ b/src/Web/StellaOps.Web/src/app/features/integrations/integration-wizard.component.spec.ts @@ -1,6 +1,6 @@ import { TestBed } from '@angular/core/testing'; -import { IntegrationProvider, IntegrationType } from '../integration-hub/integration.models'; +import { IntegrationProvider, IntegrationType, SecretAuthorityTarget } from '../integration-hub/integration.models'; import { IntegrationWizardComponent } from './integration-wizard.component'; import { IntegrationOnboardingType, resolveSupportedProviders } from './models/integration.models'; @@ -12,10 +12,13 @@ describe('IntegrationWizardComponent', () => { catalog = [ { name: 'github-app', type: IntegrationType.Scm, provider: IntegrationProvider.GitHubApp }, ], + secretTargets: SecretAuthorityTarget[] = [], ) { component = TestBed.runInInjectionContext(() => new IntegrationWizardComponent()); (component as any).integrationType = () => type; (component as any).supportedProviders = () => resolveSupportedProviders(type, catalog); + (component as any).secretTargets = () => secretTargets; + (component as any).secretTargetsError = () => null; component.draft.update((draft) => ({ ...draft, type })); } @@ -72,19 +75,21 @@ describe('IntegrationWizardComponent', () => { component.onSubmit(); - expect(emitSpy).toHaveBeenCalledWith(jasmine.objectContaining({ - name: 'GitHub App Platform', - type: IntegrationType.Scm, - provider: IntegrationProvider.GitHubApp, - endpoint: 'https://github.com', - authRefUri: 'authref://vault/github#app', - organizationId: 'platform', - extendedConfig: jasmine.objectContaining({ - appId: '12345', - installationId: '67890', - repositories: ['platform/api'], - scheduleType: 'interval', - intervalMinutes: 60, + expect(emitSpy).toHaveBeenCalledWith(expect.objectContaining({ + request: expect.objectContaining({ + name: 'GitHub App Platform', + type: IntegrationType.Scm, + provider: IntegrationProvider.GitHubApp, + endpoint: 'https://github.com', + authRefUri: 'authref://vault/github#app', + organizationId: 'platform', + extendedConfig: expect.objectContaining({ + appId: '12345', + installationId: '67890', + repositories: ['platform/api'], + scheduleType: 'interval', + intervalMinutes: 60, + }), }), })); }); @@ -102,12 +107,64 @@ describe('IntegrationWizardComponent', () => { component.onSubmit(); - expect(emitSpy).toHaveBeenCalledWith(jasmine.objectContaining({ - name: 'Local MinIO', - type: IntegrationType.ObjectStorage, - provider: IntegrationProvider.S3Compatible, - endpoint: 'http://minio.stella-ops.local:9000', - authRefUri: null, + expect(emitSpy).toHaveBeenCalledWith(expect.objectContaining({ + request: expect.objectContaining({ + name: 'Local MinIO', + type: IntegrationType.ObjectStorage, + provider: IntegrationProvider.S3Compatible, + endpoint: 'http://minio.stella-ops.local:9000', + authRefUri: null, + }), + })); + }); + + it('stages GitLab credentials through Secret Authority before create', () => { + createComponent( + 'scm', + [{ name: 'gitlab-server', type: IntegrationType.Scm, provider: IntegrationProvider.GitLabServer }], + [{ + integrationId: 'vault-1', + name: 'Local Vault', + provider: IntegrationProvider.Vault, + endpoint: 'http://vault.stella-ops.local:8200', + status: 'healthy', + logicalPathHint: 'local-vault', + supportsWrite: true, + }], + ); + component.selectProvider(IntegrationProvider.GitLabServer); + const emitSpy = jasmine.createSpy('emit'); + spyOn(component.create, 'emit').and.callFake(emitSpy); + + component.currentStep.set('auth'); + component.updateSecretStagingEnabled(true); + component.updateSecretTargetIntegrationId('vault-1'); + component.updateSecretBundleId('gitlab-server'); + component.updateSecretLogicalPath('gitlab/server'); + component.updateSecretEntry('access-token', 'glpat-123'); + component.updateName('Local GitLab'); + component.currentStep.set('review'); + + component.onSubmit(); + + expect(emitSpy).toHaveBeenCalledWith(expect.objectContaining({ + request: expect.objectContaining({ + name: 'Local GitLab', + type: IntegrationType.Scm, + provider: IntegrationProvider.GitLabServer, + endpoint: 'https://gitlab.com', + authRefUri: null, + }), + stagedSecretBundle: expect.objectContaining({ + bundleId: 'gitlab-server', + authRefKey: 'access-token', + request: expect.objectContaining({ + targetIntegrationId: 'vault-1', + logicalPath: 'gitlab/server', + overwrite: true, + entries: [{ key: 'access-token', value: 'glpat-123' }], + }), + }), })); }); }); diff --git a/src/Web/StellaOps.Web/src/app/features/integrations/integration-wizard.component.ts b/src/Web/StellaOps.Web/src/app/features/integrations/integration-wizard.component.ts index e6be12dab..aca8d3980 100644 --- a/src/Web/StellaOps.Web/src/app/features/integrations/integration-wizard.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/integrations/integration-wizard.component.ts @@ -10,15 +10,18 @@ import { } from '@angular/core'; import { FormsModule } from '@angular/forms'; -import { CreateIntegrationRequest } from '../integration-hub/integration.models'; +import { SecretAuthorityTarget } from '../integration-hub/integration.models'; import { - buildCreateIntegrationRequest, + buildIntegrationWizardSubmit, + createSecretBundleDraft, IntegrationDraft, IntegrationOnboardingType, IntegrationProviderDefinition, + IntegrationWizardSubmit, intervalOptions, PreflightCheck, resolveProviderDefinition, + resolveSecretAuthorityProfile, scheduleOptions, WizardStep, } from './models/integration.models'; @@ -34,11 +37,13 @@ import { export class IntegrationWizardComponent { readonly integrationType = input.required(); readonly supportedProviders = input([]); + readonly secretTargets = input([]); + readonly secretTargetsError = input(null); readonly creating = input(false); readonly errorMessage = input(null); readonly cancel = output(); - readonly create = output(); + readonly create = output(); readonly steps: WizardStep[] = ['provider', 'auth', 'scope', 'schedule', 'preflight', 'review']; readonly currentStep = signal('provider'); @@ -61,10 +66,15 @@ export class IntegrationWizardComponent { webhookEnabled: false, tags: [], extendedConfig: {}, + secretBundle: createSecretBundleDraft(null), }); readonly currentStepIndex = computed(() => this.steps.indexOf(this.currentStep())); readonly selectedProvider = computed(() => resolveProviderDefinition(this.draft().provider)); + readonly secretAuthorityProfile = computed(() => resolveSecretAuthorityProfile(this.draft().provider)); + readonly healthySecretTargets = computed(() => + this.secretTargets().filter((target) => target.supportsWrite && target.status === 'healthy'), + ); readonly deploymentTemplate = computed(() => null); readonly copySafetyGuidance = computed(() => [ 'Use AuthRef URIs whenever the connector requires credentials; local public probes can be created without one.', @@ -125,6 +135,7 @@ export class IntegrationWizardComponent { endpoint: draft.endpoint || definition.defaultEndpoint, organizationId: draft.organizationId, extendedConfig: this.ensureConfigDefaults(draft.extendedConfig, definition), + secretBundle: createSecretBundleDraft(provider), })); } @@ -144,6 +155,69 @@ export class IntegrationWizardComponent { this.draft.update((draft) => ({ ...draft, organizationId: value })); } + updateSecretStagingEnabled(enabled: boolean): void { + this.draft.update((draft) => ({ + ...draft, + secretBundle: { + ...draft.secretBundle, + enabled, + }, + })); + } + + updateSecretTargetIntegrationId(value: string): void { + this.draft.update((draft) => ({ + ...draft, + secretBundle: { + ...draft.secretBundle, + targetIntegrationId: value, + }, + })); + } + + updateSecretBundleId(value: string): void { + this.draft.update((draft) => ({ + ...draft, + secretBundle: { + ...draft.secretBundle, + bundleId: value, + }, + })); + } + + updateSecretLogicalPath(value: string): void { + this.draft.update((draft) => ({ + ...draft, + secretBundle: { + ...draft.secretBundle, + logicalPath: value, + }, + })); + } + + updateSecretEntry(key: string, value: string): void { + this.draft.update((draft) => ({ + ...draft, + secretBundle: { + ...draft.secretBundle, + entries: { + ...draft.secretBundle.entries, + [key]: value, + }, + }, + })); + } + + toggleSecretOverwrite(): void { + this.draft.update((draft) => ({ + ...draft, + secretBundle: { + ...draft.secretBundle, + overwrite: !draft.secretBundle.overwrite, + }, + })); + } + updateConfigField(fieldId: string, value: string): void { this.draft.update((draft) => ({ ...draft, @@ -241,12 +315,12 @@ export class IntegrationWizardComponent { } onSubmit(): void { - const request = buildCreateIntegrationRequest(this.draft()); - if (request === null) { + const submission = buildIntegrationWizardSubmit(this.draft(), this.healthySecretTargets()); + if (submission === null) { return; } - this.create.emit(request); + this.create.emit(submission); } async runPreflightChecks(): Promise { @@ -317,6 +391,38 @@ export class IntegrationWizardComponent { return this.selectedProvider()?.authRefRequired ?? true; } + supportsSecretAuthority(): boolean { + return this.secretAuthorityProfile() !== null; + } + + hasHealthySecretTargets(): boolean { + return this.healthySecretTargets().length > 0; + } + + getSelectedSecretTargetName(): string | null { + const targetId = this.draft().secretBundle.targetIntegrationId; + if (!targetId) { + return null; + } + + return this.healthySecretTargets().find((target) => target.integrationId === targetId)?.name ?? null; + } + + getResolvedAuthRefPreview(): string { + const authRefUri = this.draft().authRefUri.trim(); + if (authRefUri.length > 0) { + return authRefUri; + } + + const profile = this.secretAuthorityProfile(); + if (profile && this.hasValidStagedSecretBundle()) { + const logicalPath = this.draft().secretBundle.logicalPath.trim() || this.draft().secretBundle.bundleId.trim(); + return `authref://vault/${logicalPath}#${profile.authRefKey}`; + } + + return 'Not configured'; + } + hasScopeSelectors(): boolean { const type = this.integrationType(); return type === 'registry' || type === 'scm'; @@ -359,7 +465,7 @@ export class IntegrationWizardComponent { return false; } - if (this.isAuthRefRequired() && draft.authRefUri.trim().length === 0) { + if (this.isAuthRefRequired() && draft.authRefUri.trim().length === 0 && !this.hasValidStagedSecretBundle()) { return false; } @@ -433,6 +539,15 @@ export class IntegrationWizardComponent { checks.push({ id: 'harbor-route', name: 'Harbor health route', description: 'Harbor endpoints must answer /api/v2.0/health.', status: 'pending' }); } + if (this.supportsSecretAuthority()) { + checks.push({ + id: 'secret-authority', + name: 'Secret staging', + description: 'If inline secret staging is enabled, confirm the selected secret-authority target and bundle details are valid.', + status: 'pending', + }); + } + return checks; } @@ -444,6 +559,10 @@ export class IntegrationWizardComponent { switch (check.id) { case 'authref': + if (this.hasValidStagedSecretBundle()) { + return { status: 'success', message: `Secret Authority will mint ${this.getResolvedAuthRefPreview()} during creation.` }; + } + if (draft.authRefUri.trim().length === 0) { return this.isAuthRefRequired() ? { status: 'error', message: 'This connector requires an authref:// URI instead of embedding secrets in the connector.' } @@ -477,6 +596,14 @@ export class IntegrationWizardComponent { return draft.endpoint.trim().length > 0 ? { status: 'warning', message: 'Harbor probes expect /api/v2.0/health on the configured endpoint.' } : { status: 'error', message: 'Harbor requires a base endpoint before the health contract can be evaluated.' }; + case 'secret-authority': + if (!this.draft().secretBundle.enabled) { + return { status: 'warning', message: 'Inline secret staging is disabled; the connector will use the provided AuthRef URI if one is configured.' }; + } + + return this.hasValidStagedSecretBundle() + ? { status: 'success', message: `Secret bundle ${draft.secretBundle.logicalPath.trim() || draft.secretBundle.bundleId.trim()} will be staged before connector creation.` } + : { status: 'error', message: 'Select a healthy secret-authority target and fill every required secret bundle field.' }; default: return provider ? { status: 'success', message: `${provider.name} onboarding draft is internally consistent.` } @@ -484,6 +611,31 @@ export class IntegrationWizardComponent { } } + private hasValidStagedSecretBundle(): boolean { + const profile = this.secretAuthorityProfile(); + const draft = this.draft().secretBundle; + if (!draft.enabled || profile === null) { + return false; + } + + if (!this.hasHealthySecretTargets()) { + return false; + } + + if (draft.targetIntegrationId.trim().length === 0 || draft.bundleId.trim().length === 0) { + return false; + } + + const target = this.healthySecretTargets().find((item) => item.integrationId === draft.targetIntegrationId); + if (!target) { + return false; + } + + return profile.entryFields + .filter((field) => field.required) + .every((field) => (draft.entries[field.id] ?? '').trim().length > 0); + } + private hasExplicitScopeInputs(): boolean { const draft = this.draft(); return ( diff --git a/src/Web/StellaOps.Web/src/app/features/integrations/integrations-hub.component.ts b/src/Web/StellaOps.Web/src/app/features/integrations/integrations-hub.component.ts index 5d942502f..79df753b4 100644 --- a/src/Web/StellaOps.Web/src/app/features/integrations/integrations-hub.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/integrations/integrations-hub.component.ts @@ -1,13 +1,18 @@ import { ChangeDetectionStrategy, Component, computed, inject, OnInit, signal } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { timeout } from 'rxjs'; +import { map, of, switchMap, timeout } from 'rxjs'; import { IntegrationService } from '../integration-hub/integration.service'; -import { CreateIntegrationRequest, SupportedProviderInfo } from '../integration-hub/integration.models'; +import { + CreateIntegrationRequest, + SecretAuthorityTarget, + SupportedProviderInfo, +} from '../integration-hub/integration.models'; import { integrationWorkspaceCommands } from '../integration-hub/integration-route-context'; import { IntegrationWizardComponent } from './integration-wizard.component'; import { IntegrationOnboardingType, + IntegrationWizardSubmit, resolveSupportedProviders, } from './models/integration.models'; @@ -201,6 +206,8 @@ import { (null); readonly supportedCatalog = signal([]); + readonly secretAuthorityTargets = signal([]); readonly loadingCatalog = signal(true); readonly loadError = signal(null); + readonly secretTargetLoadError = signal(null); readonly saving = signal(false); readonly saveError = signal(null); @@ -344,6 +353,9 @@ export class IntegrationsHubComponent implements OnInit { readonly feedProviders = computed(() => resolveSupportedProviders('feed', this.supportedCatalog())); readonly secretProviders = computed(() => resolveSupportedProviders('secrets', this.supportedCatalog())); readonly storageProviders = computed(() => resolveSupportedProviders('storage', this.supportedCatalog())); + readonly healthySecretTargets = computed(() => + this.secretAuthorityTargets().filter((target) => target.supportsWrite && target.status === 'healthy'), + ); ngOnInit(): void { this.route.paramMap.subscribe((params) => { @@ -352,6 +364,7 @@ export class IntegrationsHubComponent implements OnInit { }); this.loadProviderCatalog(); + this.loadSecretAuthorityTargets(); } loadProviderCatalog(): void { @@ -404,11 +417,31 @@ export class IntegrationsHubComponent implements OnInit { }); } - onIntegrationCreated(request: CreateIntegrationRequest): void { + onIntegrationCreated(submission: IntegrationWizardSubmit): void { this.saving.set(true); this.saveError.set(null); - this.integrationService.create(request).pipe( + const createRequest = { ...submission.request }; + const createRequest$ = submission.stagedSecretBundle + ? this.integrationService + .upsertSecretBundle(submission.stagedSecretBundle.bundleId, submission.stagedSecretBundle.request) + .pipe( + map((response): CreateIntegrationRequest => { + const authRefUri = response.authRefs[submission.stagedSecretBundle!.authRefKey]; + if (!authRefUri) { + throw new Error(`Secret authority response did not include authRef '${submission.stagedSecretBundle!.authRefKey}'.`); + } + + return { + ...createRequest, + authRefUri, + }; + }), + ) + : of(createRequest); + + createRequest$.pipe( + switchMap((request) => this.integrationService.create(request)), timeout({ first: this.requestTimeoutMs }), ).subscribe({ next: (created) => { @@ -422,7 +455,27 @@ export class IntegrationsHubComponent implements OnInit { this.saveError.set( err?.name === 'TimeoutError' ? 'Creating the integration timed out before the service responded.' - : 'The integration could not be created. Verify the provider fields and try again.', + : this.describeCreateError(err), + ); + }, + }); + } + + loadSecretAuthorityTargets(): void { + this.secretTargetLoadError.set(null); + + this.integrationService.listSecretAuthorityTargets().pipe( + timeout({ first: this.requestTimeoutMs }), + ).subscribe({ + next: (response) => { + this.secretAuthorityTargets.set(response.items); + }, + error: (err) => { + this.secretAuthorityTargets.set([]); + this.secretTargetLoadError.set( + err?.name === 'TimeoutError' + ? 'Secret-authority targets did not load in time. Inline secret staging is temporarily unavailable.' + : 'Secret-authority targets could not be loaded. Inline secret staging is temporarily unavailable.', ); }, }); @@ -467,4 +520,14 @@ export class IntegrationsHubComponent implements OnInit { private integrationCommands(...segments: string[]): string[] { return integrationWorkspaceCommands(this.router.url, ...segments); } + + private describeCreateError(err: unknown): string { + const responseError = typeof err === 'object' && err !== null + ? (err as { error?: { detail?: string; title?: string } }).error + : undefined; + + return responseError?.detail + ?? responseError?.title + ?? 'The integration could not be created. Verify the provider fields and try again.'; + } } diff --git a/src/Web/StellaOps.Web/src/app/features/integrations/models/integration.models.ts b/src/Web/StellaOps.Web/src/app/features/integrations/models/integration.models.ts index abb344b5a..63bebc924 100644 --- a/src/Web/StellaOps.Web/src/app/features/integrations/models/integration.models.ts +++ b/src/Web/StellaOps.Web/src/app/features/integrations/models/integration.models.ts @@ -1,8 +1,10 @@ import { CreateIntegrationRequest, IntegrationProvider, + SecretAuthorityTarget, IntegrationType, SupportedProviderInfo, + UpsertSecretBundleRequest, } from '../../integration-hub/integration.models'; export type IntegrationOnboardingType = @@ -64,6 +66,7 @@ export interface IntegrationDraft { webhookEnabled: boolean; tags: string[]; extendedConfig: Record; + secretBundle: IntegrationSecretBundleDraft; } export interface IntegrationSchedule { @@ -72,6 +75,34 @@ export interface IntegrationSchedule { cronExpression?: string; } +export interface IntegrationSecretBundleDraft { + enabled: boolean; + targetIntegrationId: string; + bundleId: string; + logicalPath: string; + overwrite: boolean; + entries: Record; +} + +export interface IntegrationWizardStagedSecretBundle { + bundleId: string; + authRefKey: string; + request: UpsertSecretBundleRequest; +} + +export interface IntegrationWizardSubmit { + request: CreateIntegrationRequest; + stagedSecretBundle?: IntegrationWizardStagedSecretBundle | null; +} + +export interface SecretAuthorityProfile { + authRefKey: string; + description: string; + defaultBundleId: string; + defaultLogicalPath: string; + entryFields: ProviderField[]; +} + const ALL_PROVIDER_DEFINITIONS: readonly IntegrationProviderDefinition[] = [ // ── Registry providers ────────────────────────────────────────── { @@ -586,6 +617,54 @@ export const intervalOptions = [ { value: 1440, label: '24 hours' }, ] as const; +const SECRET_AUTHORITY_PROFILES: Readonly> = { + [IntegrationProvider.GitLabServer]: { + authRefKey: 'access-token', + description: 'Stage the GitLab access token into a healthy Vault target, then bind the connector to the generated authref:// URI.', + defaultBundleId: 'gitlab-server', + defaultLogicalPath: 'gitlab/server', + entryFields: [ + { + id: 'access-token', + label: 'GitLab Access Token', + required: true, + placeholder: 'glpat-...', + hint: 'Use a GitLab personal, project, or group access token with API access.', + }, + ], + }, + [IntegrationProvider.GitLabCi]: { + authRefKey: 'access-token', + description: 'Stage the GitLab CI token into a healthy Vault target before creating the CI connector.', + defaultBundleId: 'gitlab-ci', + defaultLogicalPath: 'gitlab/ci', + entryFields: [ + { + id: 'access-token', + label: 'GitLab CI Access Token', + required: true, + placeholder: 'glpat-...', + hint: 'Use a GitLab token with pipeline and deployment visibility for the selected group.', + }, + ], + }, + [IntegrationProvider.GitLabContainerRegistry]: { + authRefKey: 'registry-basic', + description: 'Stage the GitLab registry deploy token or username:password pair into a healthy Vault target.', + defaultBundleId: 'gitlab-registry', + defaultLogicalPath: 'gitlab/registry', + entryFields: [ + { + id: 'registry-basic', + label: 'Registry Basic Credential', + required: true, + placeholder: 'username:password', + hint: 'Provide the GitLab registry credential in username:password format.', + }, + ], + }, +} as const; + export function resolveSupportedProviders( type: IntegrationOnboardingType, catalog: readonly SupportedProviderInfo[], @@ -604,6 +683,31 @@ export function resolveProviderDefinition(provider: IntegrationProvider | null): return ALL_PROVIDER_DEFINITIONS.find((item) => item.provider === provider && item.exposeInUi) ?? null; } +export function resolveSecretAuthorityProfile(provider: IntegrationProvider | null): SecretAuthorityProfile | null { + if (provider === null) { + return null; + } + + return SECRET_AUTHORITY_PROFILES[provider] ?? null; +} + +export function createSecretBundleDraft(provider: IntegrationProvider | null): IntegrationSecretBundleDraft { + const profile = resolveSecretAuthorityProfile(provider); + const entries = profile?.entryFields.reduce>((state, field) => ({ + ...state, + [field.id]: '', + }), {}) ?? {}; + + return { + enabled: false, + targetIntegrationId: '', + bundleId: profile?.defaultBundleId ?? '', + logicalPath: profile?.defaultLogicalPath ?? '', + overwrite: true, + entries, + }; +} + export function toBackendIntegrationType(type: IntegrationOnboardingType | null): IntegrationType | null { switch (type) { case 'registry': @@ -676,3 +780,52 @@ export function buildCreateIntegrationRequest(draft: IntegrationDraft): CreateIn tags: draft.tags.length > 0 ? draft.tags : null, }; } + +export function buildIntegrationWizardSubmit( + draft: IntegrationDraft, + secretTargets: readonly SecretAuthorityTarget[], +): IntegrationWizardSubmit | null { + const request = buildCreateIntegrationRequest(draft); + if (request === null) { + return null; + } + + const profile = resolveSecretAuthorityProfile(draft.provider); + if (!draft.secretBundle.enabled || profile === null) { + return { request }; + } + + const target = secretTargets.find((item) => item.integrationId === draft.secretBundle.targetIntegrationId); + if (!target || !target.supportsWrite || target.status !== 'healthy') { + return null; + } + + const entries = profile.entryFields + .map((field) => ({ + key: field.id, + value: (draft.secretBundle.entries[field.id] ?? '').trim(), + })) + .filter((entry) => entry.value.length > 0); + + if (entries.length !== profile.entryFields.filter((field) => field.required).length) { + return null; + } + + return { + request, + stagedSecretBundle: { + bundleId: draft.secretBundle.bundleId.trim(), + authRefKey: profile.authRefKey, + request: { + targetIntegrationId: draft.secretBundle.targetIntegrationId, + logicalPath: draft.secretBundle.logicalPath.trim() || null, + overwrite: draft.secretBundle.overwrite, + labels: { + provider: String(draft.provider), + integrationType: draft.type ?? 'unknown', + }, + entries, + }, + }, + }; +} diff --git a/src/Web/StellaOps.Web/src/app/features/platform/ops/platform-feeds-airgap-page.component.ts b/src/Web/StellaOps.Web/src/app/features/platform/ops/platform-feeds-airgap-page.component.ts index 96d09f60a..fd6d4c18c 100644 --- a/src/Web/StellaOps.Web/src/app/features/platform/ops/platform-feeds-airgap-page.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/platform/ops/platform-feeds-airgap-page.component.ts @@ -10,7 +10,7 @@ import { } from '@angular/core'; import { CommonModule } from '@angular/common'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { ActivatedRoute, NavigationEnd, Router, RouterLink } from '@angular/router'; +import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; import { filter } from 'rxjs'; import { OPERATIONS_PATHS } from './operations-paths'; import { StellaPageTabsComponent, StellaPageTab } from '../../../shared/components/stella-page-tabs/stella-page-tabs.component'; @@ -55,7 +55,6 @@ interface FreshnessRow { standalone: true, imports: [ CommonModule, - RouterLink, StellaPageTabsComponent, MirrorListComponent, FeedVersionLockComponent, diff --git a/src/Web/StellaOps.Web/src/app/features/release-orchestrator/deployments/deployment-monitor/deployment-monitor.component.ts b/src/Web/StellaOps.Web/src/app/features/release-orchestrator/deployments/deployment-monitor/deployment-monitor.component.ts index 3dd265f4e..a101d5def 100644 --- a/src/Web/StellaOps.Web/src/app/features/release-orchestrator/deployments/deployment-monitor/deployment-monitor.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/release-orchestrator/deployments/deployment-monitor/deployment-monitor.component.ts @@ -49,7 +49,7 @@ interface WorkflowDagNode {
@@ -423,7 +423,7 @@ interface WorkflowDagNode { } @else {

Deployment not found

- Back to Deployments + Back to Deployments
} diff --git a/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/components/environment-settings/environment-settings.component.ts b/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/components/environment-settings/environment-settings.component.ts index 4df856d6d..9d5ac8723 100644 --- a/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/components/environment-settings/environment-settings.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/components/environment-settings/environment-settings.component.ts @@ -5,7 +5,7 @@ import { ReleaseEnvironmentStore } from '../../environment.store'; import type { Environment } from '../../../../../core/api/release-environment.models'; /** - * Environment settings component for configuring approvals, notifications, and limits. + * Environment settings component for configuring real release-environment controls. * Sprint: SPRINT_20260110_111_002_FE_environment_management_ui */ @Component({ @@ -14,7 +14,6 @@ import type { Environment } from '../../../../../core/api/release-environment.mo template: `
-

Approval Settings

@@ -52,81 +51,10 @@ import type { Environment } from '../../../../../core/api/release-environment.mo />
- -
- - -
-
-

Notifications

- -
- - -
- -
- - -
- -
- - -
- -
- - - Receive deployment events via webhook -
-
- - -
-

Deployment Limits

- -
- - - Maximum number of simultaneous deployments allowed -
+

Execution Settings

@@ -141,6 +69,18 @@ import type { Environment } from '../../../../../core/api/release-environment.mo /> {{ formatTimeout(settings.deploymentTimeout) }}
+ + @if (environment?.autoPromoteSourceEnvironmentId) { +
+ + + Auto-promotion topology is configured on the owning backend and is read-only in this screen. +
+ }
@@ -271,13 +211,7 @@ export class EnvironmentSettingsComponent implements OnChanges { settings = { requiresApproval: true, requiredApprovers: 1, - autoPromoteOnSuccess: false, separationOfDuties: false, - notifyOnPromotion: true, - notifyOnDeployment: true, - notifyOnFailure: true, - webhookUrl: '', - maxConcurrentDeployments: 1, deploymentTimeout: 3600, }; @@ -293,13 +227,7 @@ export class EnvironmentSettingsComponent implements OnChanges { this.settings = { requiresApproval: this.environment.requiresApproval, requiredApprovers: this.environment.requiredApprovers, - autoPromoteOnSuccess: this.environment.autoPromoteOnSuccess, separationOfDuties: this.environment.separationOfDuties, - notifyOnPromotion: this.environment.notifyOnPromotion, - notifyOnDeployment: this.environment.notifyOnDeployment, - notifyOnFailure: this.environment.notifyOnFailure, - webhookUrl: this.environment.webhookUrl || '', - maxConcurrentDeployments: this.environment.maxConcurrentDeployments, deploymentTimeout: this.environment.deploymentTimeout, }; @@ -331,13 +259,7 @@ export class EnvironmentSettingsComponent implements OnChanges { this.store.updateEnvironmentSettings(this.environment.id, { requiresApproval: this.settings.requiresApproval, requiredApprovers: this.settings.requiresApproval ? this.settings.requiredApprovers : 0, - autoPromoteOnSuccess: this.settings.autoPromoteOnSuccess, separationOfDuties: this.settings.separationOfDuties, - notifyOnPromotion: this.settings.notifyOnPromotion, - notifyOnDeployment: this.settings.notifyOnDeployment, - notifyOnFailure: this.settings.notifyOnFailure, - webhookUrl: this.settings.webhookUrl || undefined, - maxConcurrentDeployments: this.settings.maxConcurrentDeployments, deploymentTimeout: this.settings.deploymentTimeout, }); diff --git a/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/components/freeze-window-editor/freeze-window-editor.component.ts b/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/components/freeze-window-editor/freeze-window-editor.component.ts index b50b37357..b51b7e927 100644 --- a/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/components/freeze-window-editor/freeze-window-editor.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/components/freeze-window-editor/freeze-window-editor.component.ts @@ -19,7 +19,7 @@ import {

Freeze Windows

-
@@ -373,7 +373,6 @@ export class FreezeWindowEditorComponent { private readonly store = inject(ReleaseEnvironmentStore); showForm = false; - showAddDialog = false; editingWindow: FreezeWindow | null = null; deleteTarget: FreezeWindow | null = null; @@ -405,6 +404,12 @@ export class FreezeWindowEditorComponent { return new Date(window.startTime) <= now && now <= new Date(window.endTime); } + startCreate(): void { + this.editingWindow = null; + this.showForm = true; + this.resetForm(); + } + editWindow(window: FreezeWindow): void { this.editingWindow = window; this.showForm = true; @@ -434,7 +439,6 @@ export class FreezeWindowEditorComponent { cancelForm(): void { this.showForm = false; - this.showAddDialog = false; this.editingWindow = null; this.resetForm(); } diff --git a/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/components/target-list/target-list.component.ts b/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/components/target-list/target-list.component.ts index ccfed0af3..319bac7e9 100644 --- a/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/components/target-list/target-list.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/components/target-list/target-list.component.ts @@ -1,46 +1,48 @@ -import { Component, Input, inject, signal } from '@angular/core'; import { CommonModule } from '@angular/common'; +import { Component, Input, inject } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { ReleaseEnvironmentStore } from '../../environment.store'; import { + type ComposeHostConnectionConfig, + type CreateTargetRequest, type DeploymentTarget, - type TargetType, - getTargetTypeLabel, - getTargetTypeIcon, + type DockerHostConnectionConfig, + type EcsServiceConnectionConfig, getHealthStatusColor, - getAgentStatusColor, + getTargetTypeLabel, + type NomadJobConnectionConfig, + type SshHostConnectionConfig, + type TargetConnectionConfig, + type TargetType, + type UpdateTargetRequest, + type WinRmHostConnectionConfig, } from '../../../../../core/api/release-environment.models'; -/** - * Target list component for managing deployment targets. - * Sprint: SPRINT_20260110_111_002_FE_environment_management_ui - */ @Component({ - selector: 'app-target-list', - imports: [CommonModule, FormsModule], - template: ` + selector: 'app-target-list', + imports: [CommonModule, FormsModule], + template: `
-
+

Deployment Targets

@if (loading) { -
Loading targets...
+
Loading targets...
} @else if (targets.length === 0) { -
+

No deployment targets configured.

} @else { - +
- @@ -49,48 +51,17 @@ import { @for (target of targets; track target.id) { - - - + + } @@ -98,66 +69,120 @@ import {
Name Type Agent HealthRuntime Last Check Actions
-
- {{ getTypeIcon(target.type) }} - {{ target.name }} -
+ {{ target.displayName }} +
{{ target.name }}
{{ getTypeLabel(target.type) }} - - {{ target.agentId || 'Not assigned' }} - - - - {{ target.healthStatus | titlecase }} - - - - {{ getRuntimeVerificationLabel(target) }} - - {{ target.agentId || 'Not assigned' }}{{ target.healthStatus | titlecase }} {{ target.lastHealthCheck ? formatDate(target.lastHealthCheck) : 'Never' }} - - - + + +
} - @if (showAddDialog || editingTarget) { -
+

{{ editingTarget ? 'Edit Target' : 'Add Target' }}

-
- - -
-
- - -
-
- - +
+ + + +
+ + @if (targetForm.type === 'docker_host') { +
+ + + + + + +
+ } + + @if (targetForm.type === 'compose_host') { +
+ + + + + + + + +
+ } + + @if (targetForm.type === 'ecs_service') { +
+ + + + + + +
+ } + + @if (targetForm.type === 'nomad_job') { +
+ + + + + +
+ } + + @if (targetForm.type === 'ssh_host') { +
+ + + + + + +
+ } + + @if (targetForm.type === 'winrm_host') { +
+ + + + + + +
+ } + +

Secret references are sent directly to the Release Orchestrator backend.

- +
} - @if (removeTarget) { -
+

Remove Target

-

Remove {{ removeTarget.name }} from this environment?

+

Remove {{ removeTarget.displayName }} from this environment?

@@ -167,165 +192,8 @@ import { }
`, - styles: [` - .target-list h3 { - margin: 0; - } - - .list-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 1.5rem; - } - - .btn-primary { - padding: 0.5rem 1rem; - background: var(--color-btn-primary-bg); - color: var(--color-btn-primary-text); - border: none; - border-radius: var(--radius-md); - cursor: pointer; - } - - .btn-secondary { - padding: 0.5rem 1rem; - background: var(--color-surface-primary); - color: var(--color-text-primary); - border: 1px solid var(--color-border-primary); - border-radius: var(--radius-md); - cursor: pointer; - } - - .btn-danger { - padding: 0.5rem 1rem; - background: var(--color-status-error); - color: white; - border: none; - border-radius: var(--radius-md); - cursor: pointer; - } - - .loading, .empty-state { - text-align: center; - padding: 3rem; - color: var(--color-text-secondary); - } - - .target-table { - width: 100%; - border-collapse: collapse; - } - - .target-table th, - .target-table td { - padding: 0.75rem; - text-align: left; - border-bottom: 1px solid var(--color-border-primary); - } - - .target-table th { - background: var(--color-surface-primary); - font-weight: var(--font-weight-semibold); - font-size: 0.85rem; - } - - .target-name { - display: flex; - align-items: center; - gap: 0.5rem; - } - - .type-icon { - font-size: 1.25rem; - } - - .runtime-badge { - display: inline-block; - padding: 0.25rem 0.5rem; - border-radius: var(--radius-sm); - font-size: 0.75rem; - } - .runtime-verified { background: var(--color-status-success-bg, #dcfce7); color: var(--color-status-success-text, #166534); } - .runtime-drift { background: var(--color-status-warning-bg, #fef3c7); color: var(--color-status-warning-text, #92400e); } - .runtime-offline { background: var(--color-status-error-bg, #fef2f2); color: var(--color-status-error-text, #991b1b); } - .runtime-unmonitored { background: var(--color-border-primary, #e2e8f0); color: var(--color-text-muted, #64748b); border: 1px dashed var(--color-border-primary, #cbd5e1); } - - .status-badge, .health-badge { - display: inline-block; - padding: 0.25rem 0.5rem; - border-radius: var(--radius-sm); - font-size: 0.75rem; - } - - .status-success, .health-success { background: var(--color-status-success-bg); color: var(--color-status-success-text); } - .status-danger, .health-danger { background: var(--color-status-error-bg); color: var(--color-status-error-text); } - .status-secondary, .health-secondary { background: var(--color-border-primary); color: var(--color-text-primary); } - - .actions { - display: flex; - gap: 0.5rem; - } - - .actions button { - background: none; - border: none; - cursor: pointer; - padding: 0.25rem 0.5rem; - font-size: 1rem; - border-radius: var(--radius-sm); - } - - .actions button:hover { - background: var(--color-surface-primary); - } - - .actions button.danger:hover { - background: var(--color-status-error-bg); - } - - .actions button:disabled { - opacity: 0.5; - cursor: not-allowed; - } - - /* Dialog styles */ - .dialog-overlay { - position: fixed; - inset: 0; - background: rgba(0, 0, 0, 0.5); - display: flex; - align-items: center; - justify-content: center; - z-index: 1000; - } - - .dialog { - background: var(--color-surface-primary); - border-radius: var(--radius-lg); - padding: 2rem; - width: 100%; - max-width: 500px; - } - - .dialog-sm { - max-width: 400px; - } - - .dialog h2 { - margin: 0 0 1.5rem; - } - - .form-field { - margin-bottom: 1rem; - } - - .dialog-actions { - display: flex; - justify-content: flex-end; - gap: 0.5rem; - margin-top: 1.5rem; - } + styles: [` + .head,.dialog-actions,.actions{display:flex;gap:.5rem}.head{justify-content:space-between;align-items:center;margin-bottom:1rem}.empty{text-align:center;padding:2rem;color:var(--color-text-secondary)}.table{width:100%;border-collapse:collapse}.table th,.table td{padding:.75rem;text-align:left;border-bottom:1px solid var(--color-border-primary);vertical-align:top}.overlay{position:fixed;inset:0;background:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center;z-index:1000}.dialog{background:var(--color-surface-primary);border-radius:var(--radius-lg);padding:1.5rem;width:min(860px,92vw)}.dialog-sm{width:min(420px,92vw)}.grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.75rem}.grid label,.check{display:flex;flex-direction:column;gap:.25rem}.check{justify-content:flex-end}.grid input,.grid select{padding:.5rem;border:1px solid var(--color-border-primary);border-radius:var(--radius-sm)}.btn-primary,.btn-secondary,.btn-danger,.actions button{padding:.5rem .75rem;border-radius:var(--radius-md);cursor:pointer}.btn-primary{background:var(--color-btn-primary-bg);color:var(--color-btn-primary-text);border:none}.btn-secondary,.actions button{background:var(--color-surface-primary);border:1px solid var(--color-border-primary);color:var(--color-text-primary)}.btn-danger,.actions .danger{background:var(--color-status-error);border:none;color:#fff}.badge{display:inline-block;padding:.25rem .5rem;border-radius:var(--radius-sm);font-size:.75rem}.badge-success{background:var(--color-status-success-bg);color:var(--color-status-success-text)}.badge-warning{background:var(--color-status-warning-bg,#fef3c7);color:var(--color-status-warning-text,#92400e)}.badge-danger{background:var(--color-status-error-bg);color:var(--color-status-error-text)}.badge-secondary{background:var(--color-border-primary);color:var(--color-text-primary)}.muted{color:var(--color-text-secondary);font-size:.85rem} `] }) export class TargetListComponent { @@ -339,87 +207,31 @@ export class TargetListComponent { editingTarget: DeploymentTarget | null = null; removeTarget: DeploymentTarget | null = null; checkingHealth: string | null = null; + targetForm = createEmptyTargetForm(); - targetForm = { - name: '', - type: 'docker_host' as TargetType, - agentId: '', - }; - - getTypeLabel(type: TargetType): string { - return getTargetTypeLabel(type); - } - - getTypeIcon(type: TargetType): string { - const icons: Record = { - docker_host: '', - compose_host: '', - ecs_service: '', - nomad_job: '', - }; - return icons[type] || ''; - } - - getHealthColor(status: string): string { - return getHealthStatusColor(status as any); - } - - getAgentColor(status: string): string { - return getAgentStatusColor(status as any); - } - - getRuntimeVerificationLabel(target: DeploymentTarget): string { - if (!target.agentId) return 'Not monitored'; - if (target.healthStatus === 'healthy') return 'Verified'; - if (target.healthStatus === 'degraded') return 'Drift'; - if (target.healthStatus === 'unreachable') return 'Offline'; - return 'Not monitored'; - } - - getRuntimeVerificationTone(target: DeploymentTarget): string { - if (!target.agentId) return 'unmonitored'; - if (target.healthStatus === 'healthy') return 'verified'; - if (target.healthStatus === 'degraded') return 'drift'; - if (target.healthStatus === 'unreachable') return 'offline'; - return 'unmonitored'; - } - - getRuntimeVerificationTooltip(target: DeploymentTarget): string { - if (!target.agentId) return 'No agent assigned — runtime verification unavailable'; - if (target.healthStatus === 'healthy') return `Verified: containers match deployment map (last check: ${target.lastHealthCheck ? this.formatDate(target.lastHealthCheck) : 'unknown'})`; - if (target.healthStatus === 'degraded') return 'Drift detected: running containers differ from deployment map'; - if (target.healthStatus === 'unreachable') return 'Probe offline: agent not responding'; - return 'Runtime verification status unknown'; - } - - formatDate(dateStr: string): string { - return new Date(dateStr).toLocaleString(); - } + getTypeLabel(type: TargetType): string { return getTargetTypeLabel(type); } + getHealthColor(status: DeploymentTarget['healthStatus']): string { return getHealthStatusColor(status); } + getAgentTone(target: DeploymentTarget): string { return target.agentId ? 'success' : 'secondary'; } + formatDate(dateStr: string): string { return new Date(dateStr).toLocaleString(); } checkHealth(target: DeploymentTarget): void { this.checkingHealth = target.id; this.store.checkTargetHealth(this.environmentId, target.id); - setTimeout(() => { - this.checkingHealth = null; - }, 1000); + setTimeout(() => { this.checkingHealth = null; }, 1000); } editTarget(target: DeploymentTarget): void { this.editingTarget = target; - this.targetForm = { - name: target.name, - type: target.type, - agentId: target.agentId || '', - }; + this.targetForm = createEmptyTargetForm(); + this.targetForm.name = target.name; + this.targetForm.displayName = target.displayName; + this.targetForm.type = target.type; + this.targetForm.agentId = target.agentId || ''; + applyConnectionConfigToForm(this.targetForm, target.connectionConfig); } - confirmRemove(target: DeploymentTarget): void { - this.removeTarget = target; - } - - cancelRemove(): void { - this.removeTarget = null; - } + confirmRemove(target: DeploymentTarget): void { this.removeTarget = target; } + cancelRemove(): void { this.removeTarget = null; } doRemove(): void { if (this.removeTarget) { @@ -431,37 +243,92 @@ export class TargetListComponent { closeDialog(): void { this.showAddDialog = false; this.editingTarget = null; - this.resetForm(); - } - - resetForm(): void { - this.targetForm = { - name: '', - type: 'docker_host', - agentId: '', - }; + this.targetForm = createEmptyTargetForm(); } isFormValid(): boolean { - return !!(this.targetForm.name && this.targetForm.type); + if (!this.targetForm.name || !this.targetForm.displayName) return false; + switch (this.targetForm.type) { + case 'docker_host': return !!this.targetForm.docker.host; + case 'compose_host': return !!(this.targetForm.compose.host && this.targetForm.compose.composeProjectPath); + case 'ecs_service': return !!(this.targetForm.ecs.region && this.targetForm.ecs.clusterArn && this.targetForm.ecs.serviceName); + case 'nomad_job': return !!(this.targetForm.nomad.address && this.targetForm.nomad.namespace && this.targetForm.nomad.jobId); + case 'ssh_host': return !!(this.targetForm.ssh.host && this.targetForm.ssh.username); + case 'winrm_host': return !!(this.targetForm.winrm.host && this.targetForm.winrm.username); + } } saveTarget(): void { if (!this.isFormValid()) return; + const connectionConfig = buildConnectionConfig(this.targetForm); + if (!connectionConfig) return; if (this.editingTarget) { - this.store.updateTarget(this.environmentId, this.editingTarget.id, { - name: this.targetForm.name, + const request: UpdateTargetRequest = { + displayName: this.targetForm.displayName, + connectionConfig, agentId: this.targetForm.agentId || undefined, - }); + }; + this.store.updateTarget(this.environmentId, this.editingTarget.id, request); } else { - this.store.addTarget(this.environmentId, { + const request: CreateTargetRequest = { name: this.targetForm.name, + displayName: this.targetForm.displayName, type: this.targetForm.type, + connectionConfig, agentId: this.targetForm.agentId || undefined, - }); + }; + this.store.addTarget(this.environmentId, request); } this.closeDialog(); } } + +interface TargetFormState { + name: string; + displayName: string; + type: TargetType; + agentId: string; + docker: DockerHostConnectionConfig; + compose: ComposeHostConnectionConfig; + ecs: EcsServiceConnectionConfig; + nomad: NomadJobConnectionConfig; + ssh: SshHostConnectionConfig; + winrm: WinRmHostConnectionConfig; +} + +function createEmptyTargetForm(): TargetFormState { + return { + name: '', displayName: '', type: 'docker_host', agentId: '', + docker: { type: 'docker_host', host: '', port: 2376, useTls: true }, + compose: { type: 'compose_host', host: '', port: 2376, useTls: true, composeProjectPath: '', composeFile: 'docker-compose.yml' }, + ecs: { type: 'ecs_service', region: '', clusterArn: '', serviceName: '' }, + nomad: { type: 'nomad_job', address: '', namespace: 'default', jobId: '', useTls: true }, + ssh: { type: 'ssh_host', host: '', port: 22, username: '', knownHostsPolicy: 'accept' }, + winrm: { type: 'winrm_host', host: '', port: 5985, transport: 'http', username: '' }, + }; +} + +function buildConnectionConfig(form: TargetFormState): TargetConnectionConfig | null { + switch (form.type) { + case 'docker_host': return { ...form.docker }; + case 'compose_host': return { ...form.compose }; + case 'ecs_service': return { ...form.ecs }; + case 'nomad_job': return { ...form.nomad }; + case 'ssh_host': return { ...form.ssh }; + case 'winrm_host': return { ...form.winrm }; + default: return null; + } +} + +function applyConnectionConfigToForm(form: TargetFormState, config: TargetConnectionConfig): void { + switch (config.type) { + case 'docker_host': form.docker = { ...config }; break; + case 'compose_host': form.compose = { ...config }; break; + case 'ecs_service': form.ecs = { ...config }; break; + case 'nomad_job': form.nomad = { ...config }; break; + case 'ssh_host': form.ssh = { ...config }; break; + case 'winrm_host': form.winrm = { ...config }; break; + } +} diff --git a/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/environment-detail/environment-detail.component.ts b/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/environment-detail/environment-detail.component.ts index b73c94fd6..1f091e94a 100644 --- a/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/environment-detail/environment-detail.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/environment-detail/environment-detail.component.ts @@ -1,892 +1,714 @@ import { CommonModule } from '@angular/common'; -import { ChangeDetectionStrategy, Component, computed, inject, OnDestroy, OnInit, signal } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + OnDestroy, + OnInit, + computed, + effect, + inject, + signal, +} from '@angular/core'; import { Title } from '@angular/platform-browser'; import { ActivatedRoute, RouterLink } from '@angular/router'; import { BreadcrumbService } from '../../../../layout/breadcrumb'; -import { StellaPageTabsComponent, StellaPageTab } from '../../../../shared/components/stella-page-tabs/stella-page-tabs.component'; +import { StellaPageTab, StellaPageTabsComponent } from '../../../../shared/components/stella-page-tabs/stella-page-tabs.component'; +import { + DeploymentTarget, + FreezeWindow, + getHealthPercentage, + getRecurrenceLabel, + getTargetTypeLabel, +} from '../../../../core/api/release-environment.models'; +import { ReleaseEnvironmentStore } from '../environment.store'; +import { EnvironmentSettingsComponent } from '../components/environment-settings/environment-settings.component'; +import { FreezeWindowEditorComponent } from '../components/freeze-window-editor/freeze-window-editor.component'; +import { TargetListComponent } from '../components/target-list/target-list.component'; -type StatusTone = 'healthy' | 'degraded' | 'unknown'; -type DataTone = 'OK' | 'WARN' | 'FAIL'; -const ENV_CASEFILE_TABS: StellaPageTab[] = [ - { id: 'overview', label: 'Overview', icon: 'M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z|||M12 12m-3 0a3 3 0 1 0 6 0 3 3 0 1 0-6 0' }, - { id: 'deploy-status', label: 'Deploy Status', icon: 'M2 2h20v8H2z|||M2 14h20v8H2z|||M6 6h.01|||M6 18h.01' }, - { id: 'sbom-findings', label: 'SBOM Findings', icon: 'M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z' }, - { id: 'reachability', label: 'Reachability', icon: 'M22 12h-4l-3 9L9 3l-3 9H2' }, - { id: 'inputs', label: 'Inputs', icon: 'M22 12h-4l-3 9L9 3l-3 9H2' }, - { id: 'promotions', label: 'Promotions', icon: 'M22 11.08V12a10 10 0 1 1-5.93-9.14|||M22 4L12 14.01l-3-3' }, - { id: 'data-confidence', label: 'Data Confidence', icon: 'M18 20V10|||M12 20V4|||M6 20v-6' }, - { id: 'evidence-audit', label: 'Evidence Audit', icon: 'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z|||M14 2v6h6|||M16 13H8|||M16 17H8|||M10 9H8' }, -]; +type EnvironmentDetailTabId = 'overview' | 'targets' | 'freeze-windows' | 'settings'; -type EnvTabId = - | 'overview' - | 'deploy-status' - | 'sbom-findings' - | 'reachability' - | 'inputs' - | 'promotions' - | 'data-confidence' - | 'evidence-audit'; - -interface TargetRow { - name: string; - agent: string; - health: StatusTone; - heartbeat: string; -} - -interface ServiceRow { - name: string; - status: string; - digest: string; - replicas: string; -} - -interface InventoryRow { - component: string; - version: string; - digest: string; - sbom: 'OK' | 'PENDING' | 'STALE'; - critR: number; -} - -interface RuntimeVerificationRow { - name: string; - deployedDigest: string; - runningDigest: string; - status: 'verified' | 'drift' | 'unexpected' | 'missing' | 'unmonitored'; - statusLabel: string; -} - -interface ReachabilityRow { - component: string; - digest: string; - build: boolean; - image: boolean; - runtime: boolean; -} - -interface InputBindingRow { - service: string; - variable: string; - source: string; - status: 'BOUND' | 'MISSING'; -} - -interface PromotionRow { - date: string; - bundle: string; - status: string; -} - -interface AuditEventRow { - when: string; - who: string; - action: string; -} +const DETAIL_TABS: readonly StellaPageTab[] = [ + { + id: 'overview', + label: 'Overview', + icon: 'M3 12h18|||M3 6h18|||M3 18h18', + }, + { + id: 'targets', + label: 'Targets', + icon: 'M4 6h16v12H4z|||M8 10h8|||M8 14h5', + }, + { + id: 'freeze-windows', + label: 'Freeze Windows', + icon: 'M7 11V7a5 5 0 0 1 10 0v4|||M5 11h14v10H5z', + }, + { + id: 'settings', + label: 'Settings', + icon: 'M12 2v4|||M12 18v4|||M4.93 4.93l2.83 2.83|||M16.24 16.24l2.83 2.83|||M2 12h4|||M18 12h4|||M4.93 19.07l2.83-2.83|||M16.24 7.76l2.83-2.83|||M12 16a4 4 0 1 0 0-8a4 4 0 0 0 0 8', + }, +] as const; @Component({ selector: 'app-environment-detail', standalone: true, - imports: [CommonModule, RouterLink, StellaPageTabsComponent], + imports: [ + CommonModule, + RouterLink, + StellaPageTabsComponent, + TargetListComponent, + FreezeWindowEditorComponent, + EnvironmentSettingsComponent, + ], changeDetection: ChangeDetectionStrategy.OnPush, template: ` -
-
- Back to Regions & Environments +
+ Back to Environments -
-

{{ regionLabel() }}/{{ envLabel() }} Environment

- {{ envType() }} + @if (store.error()) { + + } -
-
- Deploy - {{ deployStatus() }} | targets {{ healthyTargets() }}/{{ totalTargets() }} healthy -
-
- SBOM - {{ sbomStatus() }} | scanned {{ sbomScanned() }}/{{ sbomTotal() }} | pending {{ sbomPending() }} -
-
- Findings (target env) - CritR={{ critR() }} | HighR={{ highR() }} | HighNR={{ highNR() }} | VEX={{ vexCoverage() }}% -
-
- Hybrid Reach Coverage - - Build {{ buildCoverage() }}% | Image {{ imageCoverage() }}% | Runtime {{ runtimeCoverage() }}% - (age B {{ buildAge() }} / I {{ imageAge() }} / R {{ runtimeAge() }}) - -
-
- Data Confidence - {{ dataConfidence() }} ({{ dataIssueSummary() }}) -
-
- Policy Baseline / Version Lock - {{ policyBaseline() }} / {{ versionLock() }} -
-
- Deployed Bundle - {{ deployedBundle() }} ({{ manifestDigest() }}) -
-
- - -
- - - -
- @if (activeTab() === 'overview') { -
-

Overview

-
-
-

Current Deployment

-

{{ deployedBundle() }}

-

Manifest: {{ manifestDigest() }}

-

Last promoted by: platform-release-bot

-

Components: 12 services

-
-
-

Promotion Posture

-

Pending approvals: 2

-

Active runs: 1

-

Next scheduled: 2026-02-20 01:00 UTC

-
-
-
- - - - - -
-

Top Risks

-
    - @for (risk of topRisks; track risk) { -
  • {{ risk }}
  • - } @empty { -
  • No current risks
  • + @if (loadingEnvironment()) { +
    +

    Loading environment...

    +

    Fetching the owning Release Orchestrator environment record.

    +
    + } @else if (!environment()) { +
    +

    Environment unavailable

    +

    The requested environment could not be loaded from the owning backend.

    +
    + } @else if (environment(); as currentEnvironment) { +
    +
    +

    Release Environments

    +
    +

    {{ currentEnvironment.displayName }}

    + @if (currentEnvironment.isProduction) { + Production } -
- -
- } +

{{ currentEnvironment.description || 'No description provided.' }}

+
- @if (activeTab() === 'deploy-status') { -
-

Deploy Status

- - - - - - - - - - - @for (row of targetRows; track row.name) { - - - - - - - } - -
NameAgentHealthHeartbeat
{{ row.name }}{{ row.agent }}{{ row.health }}{{ row.heartbeat }}
+
+
+ Environment ID + {{ currentEnvironment.id }} +
+
+ Created + {{ formatDateTime(currentEnvironment.createdAt) }} +
+
+ Updated + {{ currentEnvironment.updatedAt ? formatDateTime(currentEnvironment.updatedAt) : 'Never' }} +
+
+
- - - - - - - - - - - @for (row of serviceRows; track row.name) { - - - - - - - } - -
NameStatusDigestReplicas
{{ row.name }}{{ row.status }}{{ row.digest }}{{ row.replicas }}
+
+
+ Targets + {{ currentEnvironment.targetCount }} + {{ currentEnvironment.healthyTargetCount }} healthy +
+
+ Health + {{ healthPercentage() }}% + {{ healthSummary() }} +
+
+ Freeze Windows + {{ currentEnvironment.freezeWindowCount }} + {{ currentEnvironment.activeFreezeWindow ? 'Active freeze in effect' : 'No active freeze' }} +
+
+ Approvals + {{ currentEnvironment.requiresApproval ? currentEnvironment.requiredApprovers : 0 }} + {{ currentEnvironment.requiresApproval ? 'Required before deployment' : 'No approval gate' }} +
+
- -
- - Runtime Verification - - {{ verifiedContainerCount() }} verified, {{ driftContainerCount() }} drift, {{ unmonitoredContainerCount() }} unmonitored - - - - - - - - - - - - - @for (row of runtimeVerificationRows(); track row.name) { - - - - - - +
+

Truthful Surface

+

+ This page only renders environment data currently owned by the Release Orchestrator backend: + environment metadata, deployment targets, freeze windows, and promotion controls. It no longer + fabricates deployment evidence, SBOM posture, reachability, or findings rollups. +

+
+ + + + @switch (activeTab()) { + @case ('overview') { +
+
+
+

Environment Controls

+
+
Name
+
{{ currentEnvironment.name }}
+
Order
+
#{{ currentEnvironment.order }}
+
Requires Approval
+
{{ currentEnvironment.requiresApproval ? 'Yes' : 'No' }}
+
Required Approvers
+
{{ currentEnvironment.requiredApprovers }}
+
Separation of Duties
+
{{ currentEnvironment.separationOfDuties ? 'Enabled' : 'Disabled' }}
+
Deployment Timeout
+
{{ formatDuration(currentEnvironment.deploymentTimeout) }}
+ @if (currentEnvironment.autoPromoteSourceEnvironmentId) { +
Auto-Promote Source
+
{{ currentEnvironment.autoPromoteSourceEnvironmentId }}
+ } +
+
+ +
+

Target Coverage

+ @if (targets().length === 0) { +

No deployment targets are currently registered for this environment.

+ } @else { +
ContainerDeployed DigestRunning DigestStatus
{{ row.name }}{{ row.deployedDigest }}{{ row.runningDigest }} - - {{ row.statusLabel }} - -
+ + + + + + + + + + @for (target of targets(); track target.id) { + + + + + + + } + +
NameTypeHealthAgent
+ {{ target.displayName }} +
{{ target.name }}
+
{{ getTargetType(target) }} + + {{ target.healthStatus }} + + {{ target.agentId || 'Not assigned' }}
} - - -
+ + - - - } - - @if (activeTab() === 'sbom-findings') { -
-

SBOM & Findings

-

- CritR {{ critR() }} | HighR {{ highR() }} | HighNR {{ highNR() }} | - VEX {{ vexCoverage() }}% | SBOM freshness {{ sbomStatus() }} | Missing SBOM {{ missingSbom() }} -

- - - - - - - - - - - - @for (row of inventoryRows; track row.component) { - - - - - - - +
+

Freeze Schedule

+ @if (freezeWindows().length === 0) { +

No freeze windows are configured for this environment.

+ } @else { +
ComponentVersion labelDigestSBOM statusFindings (CritR)
{{ row.component }}{{ row.version }}{{ row.digest }}{{ row.sbom }}{{ row.critR }}
+ + + + + + + + + + @for (window of freezeWindows(); track window.id) { + + + + + + + } + +
NameWindowRecurrenceStatus
+ {{ window.name }} +
{{ window.reason }}
+
+ {{ formatDateTime(window.startTime) }} to {{ formatDateTime(window.endTime) }} + {{ getFreezeRecurrence(window) }} + + {{ window.isActive ? 'Active' : 'Scheduled' }} + +
} - - - -

Top CVE Issues

-
    -
  • CVE-2026-1234 in openssl (Critical Reachable)
  • -
  • CVE-2026-3101 in log4j-core (Critical Reachable)
  • -
- - -
+ + + } + @case ('targets') { +
+ +
+ } + @case ('freeze-windows') { +
+ +
+ } + @case ('settings') { +
+ +
+ } } - - @if (activeTab() === 'reachability') { -
-

Reachability

-

- Coverage: Build {{ buildCoverage() }}% | Image {{ imageCoverage() }}% | Runtime {{ runtimeCoverage() }}% - | Evidence age: Build {{ buildAge() }} | Image {{ imageAge() }} | Runtime {{ runtimeAge() }} -

-

- Policy interpretation: runtime coverage below 70% marks this environment as degraded for strict promotion gates. -

- - - - - - - - - - - - @for (row of reachabilityRows; track row.component) { - - - - - - - - } - -
ComponentDigestBuildImageRuntime
{{ row.component }}{{ row.digest }}{{ row.build ? 'Y' : 'N' }}{{ row.image ? 'Y' : 'N' }}{{ row.runtime ? 'Y' : 'N' }}
- -
- } - - @if (activeTab() === 'inputs') { -
-

Inputs

- @if (hasMissingBinding()) { -
- Impact: promotions using this env will BLOCK at Materialize Inputs. -
- } - - - - - - - - - - - @for (row of inputBindings; track row.service + row.variable) { - - - - - - - } - -
ServiceVariableSourceStatus
{{ row.service }}{{ row.variable }}{{ row.source }}{{ row.status }}
- @if (hasMissingBinding()) { - - } - -
- } - - @if (activeTab() === 'promotions') { -
-

Promotions & Approvals

-

Pending approvals

- - - - - - - - - - - - - @for (row of promotionRows; track row.bundle + row.date) { - - - - - - - } - -
DateBundleStatusActions
{{ row.date }}{{ row.bundle }}{{ row.status }} - Open Run - Evidence -
- -

Diff: proposed vs deployed indicates 2 component digest changes and 1 config snapshot delta.

- -
- } - - @if (activeTab() === 'data-confidence') { -
-

Data Confidence

-
-
-

Feeds

-

OSV OK (35m)

-

NVD WARN (3h 12m)

-

KEV OK (48m)

-
-
-

Jobs

-

sbom-nightly-rescan WARN

-

reachability-runtime-ingest FAIL

-
-
-

Integrations

-

Harbor OK

-

Jenkins WARN

-
-
-

DLQ

-

runtime-ingest bucket: 3 items

-
-
- -
- } - - @if (activeTab() === 'evidence-audit') { -
-

Evidence & Audit

- -

Latest promotion evidence pack: EVD-2026-101

-

Proof chain refs: proof://release/platform-bundle-1.3.0-rc1

-

Audit Trail

-
    - @for (event of auditEvents; track event.when + event.action) { -
  • {{ event.when }} - {{ event.who }} - {{ event.action }}
  • - } -
- -
- } - + } `, - styles: [ - ` - .env-casefile { - max-width: 1280px; - margin: 0 auto; - display: grid; - gap: 1rem; + styles: [` + .environment-detail { + display: grid; + gap: 1.5rem; + padding: 1.5rem; + max-width: 1320px; + margin: 0 auto; + } + + .back-link { + color: var(--color-text-link, var(--color-brand-primary, #2563eb)); + text-decoration: none; + font-weight: 500; + } + + .back-link:hover { + text-decoration: underline; + } + + .banner, + .state-card, + .hero, + .notice-panel, + .card { + background: var(--color-surface-primary); + border: 1px solid var(--color-border-primary); + border-radius: var(--radius-lg); + } + + .banner { + display: flex; + gap: 0.75rem; + padding: 0.9rem 1rem; + align-items: center; + } + + .banner--error { + border-color: var(--color-status-error, #dc2626); + background: var(--color-status-error-bg, rgba(220, 38, 38, 0.08)); + } + + .state-card { + padding: 1.5rem; + } + + .state-card h1 { + margin: 0 0 0.5rem; + font-size: 1.35rem; + } + + .state-card p { + margin: 0; + color: var(--color-text-secondary); + } + + .hero { + display: grid; + gap: 1rem; + padding: 1.5rem; + grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr); + } + + .eyebrow { + margin: 0 0 0.35rem; + text-transform: uppercase; + letter-spacing: 0.08em; + font-size: 0.72rem; + color: var(--color-text-secondary); + } + + .hero__title-row { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.75rem; + } + + .hero h1 { + margin: 0; + font-size: 2rem; + line-height: 1.1; + color: var(--color-text-primary); + } + + .hero__subtitle { + margin: 0.75rem 0 0; + color: var(--color-text-secondary); + max-width: 70ch; + } + + .hero__meta { + display: grid; + gap: 0.75rem; + } + + .meta-card { + display: grid; + gap: 0.25rem; + padding: 0.85rem 1rem; + border: 1px solid var(--color-border-primary); + border-radius: var(--radius-md); + background: var(--color-surface-secondary); + } + + .meta-card__label, + .metric__label { + font-size: 0.72rem; + text-transform: uppercase; + letter-spacing: 0.06em; + color: var(--color-text-secondary); + } + + .pill { + display: inline-flex; + align-items: center; + padding: 0.25rem 0.6rem; + border-radius: 999px; + font-size: 0.72rem; + font-weight: 600; + } + + .pill--production { + background: rgba(220, 38, 38, 0.12); + color: #b91c1c; + } + + .metrics { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 0.9rem; + } + + .metric { + display: grid; + gap: 0.25rem; + padding: 1rem; + border-radius: var(--radius-lg); + background: linear-gradient(135deg, rgba(15, 23, 42, 0.04), rgba(37, 99, 235, 0.08)); + border: 1px solid color-mix(in srgb, var(--color-border-primary) 75%, var(--color-brand-primary, #2563eb) 25%); + } + + .metric strong { + font-size: 1.6rem; + line-height: 1; + color: var(--color-text-primary); + } + + .metric__hint { + color: var(--color-text-secondary); + font-size: 0.85rem; + } + + .notice-panel { + padding: 1rem 1.1rem; + } + + .notice-panel h2 { + margin: 0 0 0.4rem; + font-size: 1rem; + } + + .notice-panel p { + margin: 0; + color: var(--color-text-secondary); + max-width: 80ch; + } + + .panel { + display: grid; + gap: 1rem; + } + + .panel-grid { + display: grid; + gap: 1rem; + grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); + } + + .card { + padding: 1.2rem; + } + + .card h2 { + margin: 0 0 1rem; + font-size: 1.05rem; + } + + .definition-list { + margin: 0; + display: grid; + grid-template-columns: minmax(0, 180px) minmax(0, 1fr); + gap: 0.55rem 0.75rem; + } + + .definition-list dt { + color: var(--color-text-secondary); + font-size: 0.82rem; + } + + .definition-list dd { + margin: 0; + color: var(--color-text-primary); + word-break: break-word; + } + + .table { + width: 100%; + border-collapse: collapse; + } + + .table th, + .table td { + padding: 0.7rem 0.5rem; + border-bottom: 1px solid var(--color-border-primary); + text-align: left; + vertical-align: top; + } + + .table th { + font-size: 0.72rem; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--color-text-secondary); + } + + .table tr:last-child td { + border-bottom: none; + } + + .muted { + color: var(--color-text-secondary); + font-size: 0.82rem; + } + + .status-pill { + display: inline-flex; + align-items: center; + padding: 0.25rem 0.55rem; + border-radius: 999px; + font-size: 0.78rem; + text-transform: capitalize; + background: var(--color-surface-secondary); + } + + .status-pill--healthy { + background: rgba(34, 197, 94, 0.14); + color: #166534; + } + + .status-pill--degraded { + background: rgba(245, 158, 11, 0.18); + color: #92400e; + } + + .status-pill--unhealthy, + .status-pill--unreachable { + background: rgba(220, 38, 38, 0.14); + color: #b91c1c; + } + + .status-pill--unknown { + background: rgba(148, 163, 184, 0.18); + color: #334155; + } + + code { + font-family: var(--font-mono, monospace); + font-size: 0.84rem; + word-break: break-all; + } + + @media (max-width: 980px) { + .hero, + .panel-grid, + .metrics { + grid-template-columns: 1fr; } - .env-header, - .tab-panel { - border: 1px solid var(--color-border-primary); - border-radius: var(--radius-lg); - background: var(--color-surface-primary); - padding: 1rem; + .definition-list { + grid-template-columns: 1fr; } - - .back-link { - color: var(--color-text-link); - text-decoration: none; - font-size: 0.82rem; - } - - .header-row { - margin-top: 0.5rem; - display: flex; - justify-content: space-between; - gap: 0.75rem; - align-items: center; - } - - h1, - h2, - h3 { - margin: 0; - } - - .type-pill { - font-size: 0.72rem; - padding: 0.15rem 0.5rem; - border-radius: var(--radius-full); - background: var(--color-surface-secondary); - } - - .header-grid { - margin-top: 0.75rem; - display: grid; - grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); - gap: 0.65rem; - } - - .header-grid .k { - display: block; - font-size: 0.68rem; - color: var(--color-text-secondary); - text-transform: uppercase; - letter-spacing: 0.04em; - } - - .header-grid .v { - font-size: 0.82rem; - } - - .quick-links { - margin-top: 0.8rem; - display: flex; - flex-wrap: wrap; - gap: 0.75rem; - } - - .quick-links a, - .footer-links a { - color: var(--color-text-link); - text-decoration: none; - font-size: 0.82rem; - } - - .tab-nav { - display: flex; - flex-wrap: wrap; - gap: 0.45rem; - } - - .tab-nav button { - border: 1px solid var(--color-border-primary); - background: var(--color-surface-primary); - color: var(--color-text-secondary); - padding: 0.45rem 0.7rem; - border-radius: var(--radius-md); - cursor: pointer; - font-size: 0.8rem; - } - - .tab-nav button.active { - color: var(--color-text-link); - border-color: var(--color-brand-primary); - background: var(--color-brand-soft); - } - - .tab-panel { - display: grid; - gap: 0.75rem; - } - - .tab-panel p, - .tab-panel li { - font-size: 0.84rem; - } - - .two-col { - display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 0.75rem; - } - - .card { - border: 1px solid var(--color-border-primary); - border-radius: var(--radius-md); - background: var(--color-surface-secondary); - padding: 0.65rem; - } - - .actions { - display: flex; - flex-wrap: wrap; - gap: 0.45rem; - margin-top: 0.75rem; - } - - button { - border: 1px solid var(--color-border-primary); - background: var(--color-surface-primary); - color: var(--color-text-primary); - border-radius: var(--radius-md); - padding: 0.35rem 0.55rem; - font-size: 0.8rem; - cursor: pointer; - } - - table { - width: 100%; - border-collapse: collapse; - margin-top: 0.65rem; - } - - th, - td { - border-bottom: 1px solid var(--color-border-primary); - padding: 0.45rem; - text-align: left; - font-size: 0.8rem; - vertical-align: top; - } - - th { - font-size: 0.68rem; - text-transform: uppercase; - letter-spacing: 0.04em; - color: var(--color-text-secondary); - } - - code { - font-size: 0.72rem; - } - - .status-chip { - border-radius: var(--radius-full); - padding: 0.1rem 0.42rem; - font-size: 0.65rem; - font-weight: var(--font-weight-semibold); - } - - .status-chip--healthy, - .status-chip--ok { - background: var(--color-status-success-bg); - color: var(--color-status-success-text); - } - - .status-chip--degraded, - .status-chip--pending, - .status-chip--stale, - .status-chip--warn { - background: var(--color-status-warning-bg); - color: var(--color-status-warning-text); - } - - .status-chip--unknown, - .status-chip--fail, - .status-chip--missing { - background: var(--color-status-error-bg); - color: var(--color-status-error-text); - } - - .warning-banner { - border: 1px solid var(--color-status-error-text); - background: var(--color-status-error-bg); - color: var(--color-status-error-text); - border-radius: var(--radius-md); - padding: 0.55rem; - margin-bottom: 0.55rem; - font-size: 0.82rem; - } - - .missing-row { - background: rgba(220, 38, 38, 0.08); - } - - .runtime-verification { margin-top: 0.75rem; border: 1px solid var(--color-border-primary, #e2e8f0); border-radius: 8px; } - .runtime-verification__header { padding: 0.75rem 1rem; cursor: pointer; font-weight: 600; font-size: 0.875rem; display: flex; justify-content: space-between; align-items: center; } - .runtime-verification__summary { font-weight: 400; font-size: 0.8125rem; color: var(--color-text-muted, #64748b); } - .runtime-verification__table { width: 100%; border-collapse: collapse; } - .runtime-verification__table th, - .runtime-verification__table td { padding: 0.5rem 0.75rem; text-align: left; border-top: 1px solid var(--color-border-primary, #e2e8f0); font-size: 0.8125rem; } - .runtime-verification__table th { font-weight: 600; background: var(--color-surface-secondary, #f8fafc); } - .rv-row--drift, .rv-row--unexpected { background: rgba(234, 179, 8, 0.06); } - .rv-row--missing { background: rgba(220, 38, 38, 0.06); } - .rv-badge { display: inline-block; padding: 0.125rem 0.5rem; border-radius: 999px; font-size: 0.75rem; font-weight: 500; } - .rv-badge--verified { background: var(--color-status-success-bg, #dcfce7); color: var(--color-status-success-text, #166534); } - .rv-badge--drift { background: var(--color-status-warning-bg, #fef3c7); color: var(--color-status-warning-text, #92400e); } - .rv-badge--unexpected { background: var(--color-status-warning-bg, #fef3c7); color: var(--color-status-warning-text, #92400e); } - .rv-badge--missing { background: var(--color-status-error-bg, #fef2f2); color: var(--color-status-error-text, #991b1b); } - .rv-badge--unmonitored { background: var(--color-border-primary, #e2e8f0); color: var(--color-text-muted, #64748b); } - - .footer-links { - margin-top: 0.7rem; - display: flex; - flex-wrap: wrap; - gap: 0.7rem; - } - - .muted { - color: var(--color-text-secondary); - } - - @media (max-width: 900px) { - .two-col { - grid-template-columns: 1fr; - } - } - `, - ], + } + `], }) export class EnvironmentDetailComponent implements OnInit, OnDestroy { private readonly route = inject(ActivatedRoute); private readonly title = inject(Title); private readonly breadcrumbService = inject(BreadcrumbService); - readonly ENV_CASEFILE_TABS = ENV_CASEFILE_TABS; - readonly activeTab = signal('overview'); + readonly store = inject(ReleaseEnvironmentStore); + readonly tabs = DETAIL_TABS; + readonly activeTab = signal('overview'); + readonly environmentId = signal(''); + readonly environment = computed(() => { + const selected = this.store.selectedEnvironment(); + return selected && selected.id === this.environmentId() ? selected : null; + }); + readonly targets = computed(() => this.store.targets()); + readonly freezeWindows = computed(() => this.store.freezeWindows()); + readonly loadingEnvironment = computed(() => { + const currentId = this.environmentId(); + const current = this.environment(); + return this.store.loading() && (!!currentId && current === null); + }); + readonly healthPercentage = computed(() => { + const current = this.environment(); + return current ? getHealthPercentage(current) : 0; + }); + readonly healthSummary = computed(() => { + const current = this.environment(); + if (!current) { + return 'No target data'; + } - readonly regionLabel = signal('global'); - readonly envLabel = signal('prod'); - readonly envType = signal('Production'); + if (current.targetCount === 0) { + return 'No targets registered'; + } - readonly deployStatus = signal('DEGRADED'); - readonly healthyTargets = signal(2); - readonly totalTargets = signal(3); + return `${current.healthyTargetCount} of ${current.targetCount} targets healthy`; + }); - readonly sbomStatus = signal('STALE'); - readonly sbomScanned = signal(10); - readonly sbomTotal = signal(12); - readonly sbomPending = signal(2); + constructor() { + effect(() => { + const current = this.environment(); + const currentId = this.environmentId(); - readonly critR = signal(3); - readonly highR = signal(6); - readonly highNR = signal(9); - readonly vexCoverage = signal(83); + if (current) { + this.title.setTitle(`${current.displayName} Environment - StellaOps`); + this.breadcrumbService.setContextCrumbs([ + { label: 'Environments', route: '/releases/environments' }, + { label: current.displayName }, + ]); + return; + } - readonly buildCoverage = signal(84); - readonly imageCoverage = signal(92); - readonly runtimeCoverage = signal(61); - readonly buildAge = signal('42m'); - readonly imageAge = signal('38m'); - readonly runtimeAge = signal('2h 11m'); - - readonly dataConfidence = signal('WARN'); - readonly dataIssueSummary = signal('NVD stale, runtime ingest lagging'); - readonly policyBaseline = signal('prod-baseline-v4.2'); - readonly versionLock = signal('prod-lock-2026-02'); - - readonly deployedBundle = signal('Platform Bundle 1.3.0-rc1'); - readonly manifestDigest = signal('sha256:env-manifest-7aa1b2c3d4e5f6a7b8'); - readonly missingSbom = signal(2); - - readonly tabs: Array<{ id: EnvTabId; label: string }> = [ - { id: 'overview', label: 'Overview' }, - { id: 'deploy-status', label: 'Deploy Status' }, - { id: 'sbom-findings', label: 'SBOM & Findings' }, - { id: 'reachability', label: 'Reachability' }, - { id: 'inputs', label: 'Inputs' }, - { id: 'promotions', label: 'Promotions' }, - { id: 'data-confidence', label: 'Data Confidence' }, - { id: 'evidence-audit', label: 'Evidence & Audit' }, - ]; - - readonly topRisks = [ - 'CVE-2026-1234 in openssl is critical reachable in api-gateway', - 'Runtime ingest backlog may downgrade promotion confidence', - '2 stale SBOM artifacts for production services', - ]; - - readonly targetRows: TargetRow[] = [ - { name: 'prod-eu-01', agent: 'agent-eu-a', health: 'healthy', heartbeat: '23s ago' }, - { name: 'prod-eu-02', agent: 'agent-eu-b', health: 'degraded', heartbeat: '58s ago' }, - { name: 'prod-eu-03', agent: 'agent-eu-c', health: 'unknown', heartbeat: '4m ago' }, - ]; - - readonly serviceRows: ServiceRow[] = [ - { name: 'api-gateway', status: 'Running', digest: 'sha256:api123', replicas: '3/3' }, - { name: 'payments-worker', status: 'Degraded', digest: 'sha256:wrk456', replicas: '1/2' }, - { name: 'event-router', status: 'Running', digest: 'sha256:evt789', replicas: '2/2' }, - ]; - - // Runtime Verification — sourced from inventory snapshot + eBPF probe observations - readonly runtimeVerificationRows = signal([ - { name: 'api-gateway', deployedDigest: 'sha256:api123…', runningDigest: 'sha256:api123…', status: 'verified', statusLabel: 'Verified' }, - { name: 'payments-worker', deployedDigest: 'sha256:wrk456…', runningDigest: 'sha256:wrk999…', status: 'drift', statusLabel: 'Digest Mismatch' }, - { name: 'event-router', deployedDigest: 'sha256:evt789…', runningDigest: 'sha256:evt789…', status: 'verified', statusLabel: 'Verified' }, - { name: 'legacy-cron', deployedDigest: '(not in map)', runningDigest: 'sha256:lcr001…', status: 'unexpected', statusLabel: 'Unexpected' }, - ]); - - readonly verifiedContainerCount = computed(() => this.runtimeVerificationRows().filter(r => r.status === 'verified').length); - readonly driftContainerCount = computed(() => this.runtimeVerificationRows().filter(r => r.status === 'drift' || r.status === 'unexpected' || r.status === 'missing').length); - readonly unmonitoredContainerCount = computed(() => this.runtimeVerificationRows().filter(r => r.status === 'unmonitored').length); - readonly hasRuntimeDrift = computed(() => this.driftContainerCount() > 0); - - readonly inventoryRows: InventoryRow[] = [ - { component: 'api-gateway', version: '2.3.1', digest: 'sha256:api123', sbom: 'OK', critR: 1 }, - { component: 'payments-worker', version: '5.4.0', digest: 'sha256:wrk456', sbom: 'STALE', critR: 2 }, - { component: 'event-router', version: '1.9.2', digest: 'sha256:evt789', sbom: 'PENDING', critR: 0 }, - ]; - - readonly reachabilityRows: ReachabilityRow[] = [ - { component: 'api-gateway', digest: 'sha256:api123', build: true, image: true, runtime: false }, - { component: 'payments-worker', digest: 'sha256:wrk456', build: true, image: true, runtime: true }, - { component: 'event-router', digest: 'sha256:evt789', build: true, image: false, runtime: false }, - ]; - - readonly inputBindings: InputBindingRow[] = [ - { service: 'api-gateway', variable: 'DB_URL', source: 'vault://kv/prod/api/db_url', status: 'BOUND' }, - { service: 'payments-worker', variable: 'REDIS_URL', source: 'consul://prod/payments/redis', status: 'BOUND' }, - { service: 'payments-worker', variable: 'KMS_KEY', source: 'vault://kv/prod/payments/kms_key', status: 'MISSING' }, - ]; - - readonly promotionRows: PromotionRow[] = [ - { date: '2026-02-19 17:10 UTC', bundle: 'Platform Bundle 1.3.0-rc1', status: 'PROMOTING' }, - { date: '2026-02-18 03:10 UTC', bundle: 'Platform Bundle 1.2.9', status: 'DEPLOYED' }, - ]; - - readonly auditEvents: AuditEventRow[] = [ - { when: '2026-02-19 16:42 UTC', who: 'ops-admin', action: 'Updated Vault path mapping for KMS_KEY' }, - { when: '2026-02-19 14:18 UTC', who: 'release-bot', action: 'Applied bundle lock prod-lock-2026-02' }, - ]; + if (currentId) { + this.title.setTitle(`${currentId} Environment - StellaOps`); + this.breadcrumbService.setContextCrumbs([ + { label: 'Environments', route: '/releases/environments' }, + { label: currentId }, + ]); + } + }); + } ngOnInit(): void { - const params = this.route.snapshot.paramMap; - const region = params.get('region') ?? 'global'; - const env = params.get('env') ?? params.get('id') ?? 'prod'; + const snapshot = this.route.snapshot; + const environmentId = snapshot.paramMap.get('environmentId') + ?? snapshot.paramMap.get('env') + ?? ''; - this.regionLabel.set(region); - this.envLabel.set(env); - this.envType.set(this.isProductionEnv(env) ? 'Production' : 'Staging'); - this.title.setTitle(`${region}/${env} Environment - StellaOps`); - this.breadcrumbService.setContextCrumbs([ - { label: region, route: `/releases/environments/${region}` }, - { label: env }, - ]); + this.environmentId.set(environmentId); + this.activeTab.set(this.resolveInitialTab()); - const queryTab = this.route.snapshot.queryParamMap.get('tab') as EnvTabId | null; - const routeTab = this.route.snapshot.data['initialTab'] as EnvTabId | undefined; - const initialTab = queryTab ?? routeTab ?? null; - if (initialTab && this.tabs.some((tab) => tab.id === initialTab)) { - this.activeTab.set(initialTab); + if (environmentId) { + this.store.loadEnvironment(environmentId); } } ngOnDestroy(): void { + this.environmentId.set(''); + this.store.selectEnvironment(null); this.breadcrumbService.clearContextCrumbs(); } - setTab(tab: EnvTabId): void { - this.activeTab.set(tab); + setActiveTab(tabId: string): void { + this.activeTab.set(this.normalizeTabId(tabId)); } - hasMissingBinding(): boolean { - return this.inputBindings.some((row) => row.status === 'MISSING'); + getTargetType(target: DeploymentTarget): string { + return getTargetTypeLabel(target.type); } - private isProductionEnv(env: string): boolean { - const normalized = env.toLowerCase(); - return normalized.includes('prod') || normalized.includes('production'); + getFreezeRecurrence(window: FreezeWindow): string { + return getRecurrenceLabel(window.recurrence); + } + + formatDateTime(value: string): string { + return new Date(value).toLocaleString(); + } + + formatFreezeWindow(window: FreezeWindow): string { + return `${window.name}: ${this.formatDateTime(window.startTime)} to ${this.formatDateTime(window.endTime)}`; + } + + formatDuration(seconds: number): string { + if (seconds < 3600) { + const minutes = Math.max(1, Math.round(seconds / 60)); + return `${minutes} minute${minutes === 1 ? '' : 's'}`; + } + + const hours = Math.floor(seconds / 3600); + const minutes = Math.floor((seconds % 3600) / 60); + + if (minutes === 0) { + return `${hours} hour${hours === 1 ? '' : 's'}`; + } + + return `${hours} hour${hours === 1 ? '' : 's'} ${minutes} min`; + } + + private resolveInitialTab(): EnvironmentDetailTabId { + const queryValue = this.route.snapshot.queryParamMap.get('tab'); + if (queryValue) { + return this.normalizeTabId(queryValue); + } + + const routeValue = this.route.snapshot.data['initialTab']; + if (typeof routeValue === 'string') { + return this.normalizeTabId(routeValue); + } + + return 'overview'; + } + + private normalizeTabId(value: string): EnvironmentDetailTabId { + switch (value) { + case 'targets': + case 'freeze-windows': + case 'settings': + case 'overview': + return value; + case 'inputs': + return 'settings'; + default: + return 'overview'; + } } } diff --git a/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/environment-list/environment-list.component.ts b/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/environment-list/environment-list.component.ts index 06dc3a0d0..fd0b80de2 100644 --- a/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/environment-list/environment-list.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/environment-list/environment-list.component.ts @@ -59,7 +59,7 @@ import {
#{{ env.order }} - + {{ env.displayName }} @if (env.isProduction) { @@ -69,8 +69,8 @@ import { @if (openMenuId === env.id) { diff --git a/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/environment.store.ts b/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/environment.store.ts index 573b8d6af..3763012ce 100644 --- a/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/environment.store.ts +++ b/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/environment.store.ts @@ -211,10 +211,7 @@ export class ReleaseEnvironmentStore { this.api.addTarget(environmentId, request).subscribe({ next: (target) => { this._targets.update((targets) => [...targets, target]); - // Update environment target count - this._selectedEnvironment.update((env) => - env ? { ...env, targetCount: env.targetCount + 1 } : null - ); + this.refreshEnvironmentSummary(environmentId); this._loading.set(false); }, error: (err) => { @@ -255,10 +252,7 @@ export class ReleaseEnvironmentStore { this.api.removeTarget(environmentId, targetId).subscribe({ next: () => { this._targets.update((targets) => targets.filter((t) => t.id !== targetId)); - // Update environment target count - this._selectedEnvironment.update((env) => - env ? { ...env, targetCount: env.targetCount - 1 } : null - ); + this.refreshEnvironmentSummary(environmentId); this._loading.set(false); }, error: (err) => { @@ -277,10 +271,11 @@ export class ReleaseEnvironmentStore { this._targets.update((targets) => targets.map((t) => t.id === targetId - ? { ...t, healthStatus: result.healthStatus, lastHealthCheck: result.checkedAt } + ? { ...t, healthStatus: result.healthStatus, healthMessage: result.message, lastHealthCheck: result.checkedAt } : t ) ); + this.refreshEnvironmentSummary(environmentId); }, error: (err) => { console.error('Failed to check target health:', err); @@ -312,10 +307,7 @@ export class ReleaseEnvironmentStore { this.api.createFreezeWindow(environmentId, request).subscribe({ next: (window) => { this._freezeWindows.update((windows) => [...windows, window]); - // Update environment freeze window count - this._selectedEnvironment.update((env) => - env ? { ...env, freezeWindowCount: env.freezeWindowCount + 1 } : null - ); + this.refreshEnvironmentSummary(environmentId); this._loading.set(false); }, error: (err) => { @@ -356,10 +348,7 @@ export class ReleaseEnvironmentStore { this.api.deleteFreezeWindow(environmentId, windowId).subscribe({ next: () => { this._freezeWindows.update((windows) => windows.filter((w) => w.id !== windowId)); - // Update environment freeze window count - this._selectedEnvironment.update((env) => - env ? { ...env, freezeWindowCount: env.freezeWindowCount - 1 } : null - ); + this.refreshEnvironmentSummary(environmentId); this._loading.set(false); }, error: (err) => { @@ -396,4 +385,21 @@ export class ReleaseEnvironmentStore { clearError(): void { this._error.set(null); } + + private refreshEnvironmentSummary(environmentId: string): void { + this.api.getEnvironment(environmentId).subscribe({ + next: (environment) => { + this._environments.update((items) => + items.map((item) => (item.id === environmentId ? environment : item)) + ); + + if (this._selectedEnvironment()?.id === environmentId) { + this._selectedEnvironment.set(environment); + } + }, + error: (err) => { + console.error('Failed to refresh environment summary:', err); + }, + }); + } } diff --git a/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/environments.routes.ts b/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/environments.routes.ts index 617c7aaa4..d356d2915 100644 --- a/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/environments.routes.ts +++ b/src/Web/StellaOps.Web/src/app/features/release-orchestrator/environments/environments.routes.ts @@ -1,22 +1,43 @@ -import { Routes } from '@angular/router'; +import { inject } from '@angular/core'; +import { Router, Routes } from '@angular/router'; + +type RedirectSnapshot = { + params: Record; + queryParams: Record; + fragment?: string | null; +}; + +function preserveEnvironmentRedirect(template: string) { + return ({ params, queryParams, fragment }: RedirectSnapshot) => { + const router = inject(Router); + let targetPath = template; + + for (const [name, value] of Object.entries(params ?? {})) { + targetPath = targetPath.replaceAll(`:${name}`, encodeURIComponent(value)); + } + + const target = router.parseUrl(targetPath); + target.queryParams = { ...queryParams }; + target.fragment = fragment ?? null; + return target; + }; +} /** - * Environment management routes for Release JobEngine. - * Sprint: SPRINT_20260110_111_002_FE_environment_management_ui - * Updated: SPRINT_20260218_013_FE_ui_v2_rewire_environment_detail_standardization (E8-01 through E8-05) - * — Added canonical breadcrumbs and tab data to list and detail routes. + * Real release-environment management routes backed by the owning + * Release Orchestrator environment API. */ export const ENVIRONMENT_ROUTES: Routes = [ { path: '', - data: { breadcrumb: 'Regions & Environments' }, + data: { breadcrumb: 'Environments' }, loadComponent: () => import('./environment-list/environment-list.component').then( (m) => m.EnvironmentListComponent ), }, { - path: ':region/:env', + path: ':environmentId', title: 'Environment Detail', loadComponent: () => import('./environment-detail/environment-detail.component').then( @@ -24,12 +45,32 @@ export const ENVIRONMENT_ROUTES: Routes = [ ), }, { - path: ':region/:env/settings', + path: ':environmentId/settings', title: 'Environment Detail', - data: { initialTab: 'inputs' }, + data: { initialTab: 'settings' }, loadComponent: () => import('./environment-detail/environment-detail.component').then( (m) => m.EnvironmentDetailComponent ), }, + { + path: ':region/environments/:env', + pathMatch: 'full', + redirectTo: preserveEnvironmentRedirect('/releases/environments/:env'), + }, + { + path: ':region/environments/:env/settings', + pathMatch: 'full', + redirectTo: preserveEnvironmentRedirect('/releases/environments/:env/settings'), + }, + { + path: ':region/:env', + pathMatch: 'full', + redirectTo: preserveEnvironmentRedirect('/releases/environments/:env'), + }, + { + path: ':region/:env/settings', + pathMatch: 'full', + redirectTo: preserveEnvironmentRedirect('/releases/environments/:env/settings'), + }, ]; diff --git a/src/Web/StellaOps.Web/src/app/features/scheduler-ops/scheduler-ops.routes.ts b/src/Web/StellaOps.Web/src/app/features/scheduler-ops/scheduler-ops.routes.ts index f7be4d347..2dede5ef6 100644 --- a/src/Web/StellaOps.Web/src/app/features/scheduler-ops/scheduler-ops.routes.ts +++ b/src/Web/StellaOps.Web/src/app/features/scheduler-ops/scheduler-ops.routes.ts @@ -38,7 +38,7 @@ export const schedulerOpsRoutes: Routes = [ }, { path: 'workers', - redirectTo: '/ops/operations/jobengine?tab=schedules', + redirectTo: '/ops/operations/jobengine?tab=workers', pathMatch: 'full', }, ]; diff --git a/src/Web/StellaOps.Web/src/app/features/scheduler-ops/scheduler-runs.component.ts b/src/Web/StellaOps.Web/src/app/features/scheduler-ops/scheduler-runs.component.ts index 7c88f9f9b..098b9fa1c 100644 --- a/src/Web/StellaOps.Web/src/app/features/scheduler-ops/scheduler-runs.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/scheduler-ops/scheduler-runs.component.ts @@ -17,14 +17,14 @@ import { OPERATIONS_PATHS, schedulerRunStreamPath } from '../platform/ops/operat import { DateFormatService } from '../../core/i18n/date-format.service'; import { StellaFilterMultiComponent, type FilterMultiOption } from '../../shared/components/stella-filter-multi/stella-filter-multi.component'; -import { StellaFilterChipComponent, type FilterChipOption } from '../../shared/components/stella-filter-chip/stella-filter-chip.component'; +import type { FilterChipOption } from '../../shared/components/stella-filter-chip/stella-filter-chip.component'; /** * Scheduler Runs Component (Sprint: SPRINT_20251229_017) * Lists scheduler runs with real-time updates and cancel/retry actions. */ @Component({ selector: 'app-scheduler-runs', - imports: [FormsModule, RouterLink, StellaFilterMultiComponent, StellaFilterChipComponent], + imports: [FormsModule, RouterLink, StellaFilterMultiComponent], template: `