Commit Graph

94 Commits

Author SHA1 Message Date
kitos 504dfc52f5 feat(auth): make email the unique login identifier
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Login is now by email, not username. username still exists internally
(JWT sub claim, audit logs, Jira actor attribution, SSO provisioning all
still key off it) but is now always kept equal to email everywhere a user
is created or their email changes — never a separately-chosen value.

- User.email is now unique + NOT NULL (migration b067 backfills any
  missing/blank email from username first, so existing rows — notably
  the seeded admin, which historically had none — never violate it).
- /auth/login and the (unused but updated for consistency)
  authenticate_user() now query by email.
- create_user (legacy, unreferenced but kept) and
  create_user_without_password both derive username from email.
- update_user keeps username in sync when email changes, and rejects
  duplicate emails.
- seed.py reads ADMIN_EMAIL (new env var, wired through install.sh and
  docker-compose.prod.yml) for the initial admin; falls back to an
  email-shaped ADMIN_USERNAME or a placeholder that's flagged for the
  operator to fix.
- admin_config.py's import bundle now matches/creates users by email,
  skipping (not crashing on) entries with no email.
- sso_service.py always sets username = email for SSO-provisioned users.
- LoginPage/auth.ts updated to email input/copy (wire field name stays
  'username' — that's the OAuth2PasswordRequestForm spec, not the value).
2026-07-23 14:39:36 +02:00
kitos d932134975 feat(users): admin can permanently delete users, fix set-password redirect bug
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
- New DELETE /users/{id}: hard-deletes a user only if they have zero
  activity footprint (no tests, evidence, worklogs, audit entries, Jira
  links, procedure/template suggestions, reviewed imports) — otherwise
  rejects with a clear message to deactivate instead, to keep the audit
  trail intact. Cleans up the user's own notifications/password-setup
  tokens as part of deletion. Self-delete is blocked. Wired to a trash
  icon in the Users page with a confirm dialog.
- Registered the EvaluationImport model in app/models/__init__.py — it
  was missing, so its table never existed in the SQLite test DB; only
  surfaced once the new delete-user footprint check queried it.
- Fixed a redirect bug: the axios response interceptor's on-401 redirect
  to /login didn't exempt /set-password, so the auth provider's routine
  mount-time /auth/me check (401 for a logged-out visitor) bounced anyone
  opening their emailed set-password link away before they could use it.
2026-07-23 08:58:17 +02:00
kitos 1d0d880929 feat(email): generic webhook for all notification emails, hide SMTP UI
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
- Renamed the password-setup webhook (email_webhook.*, /system/email-webhook-config)
  and made it the single transport for all notification emails.
- New webhook_email_service.py shared by password_setup_service and
  notification_service.
- Wired test validated/rejected, campaign completed, and new-MITRE-technique
  notifications through the webhook (previously dead SMTP code, never triggered).
- Added POST /system/email-webhook-test to send a real test email.
- Hid the Email/SMTP settings tab from the UI (SMTP code kept intact, unused).
- Redact email_webhook.api_key on config export.
2026-07-20 10:24:15 +02:00
kitos bbe7f49c86 feat(tests,users): blocking procedure-suggestion review on test detail, multi-role switcher, Power Automate webhook payload
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
- A lead opening a test with a pending procedure suggestion awaiting
  their review now gets a blocking popup (approve/reject only) instead
  of discovering it later in a separate queue.
- Users can be granted more than one role via extra_roles; only one is
  ever active at a time (no permission mixing) and a top-bar switcher
  lets the user swap which one, taking effect immediately since role
  is read fresh from the DB on every request.
- The password-setup/reset webhook now posts the agreed Power Automate
  contract ({to, subject, body} with the platform's standard greeting
  and signature template) and supports an admin-configured API key
  sent as an x-api-key header.
2026-07-20 09:29:36 +02:00
kitos 4dea19cae9 feat(users): passwordless user creation via emailed set-password link, display full name instead of username
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Admins now create users with a name + email (no password) and role;
a Send Email action (per-user, also reusable for resets) issues a
one-time token and POSTs it to an admin-configurable webhook URL —
intended for a Power Automate flow that delivers the actual email.
The old admin-sets-the-password flow is kept server-side
(LegacyUserCreateWithPassword) but no longer wired into the UI.

Every user-facing surface (top bar, sidebar, user management, audit
log, assignee pickers, dispute notifications) now shows full_name
instead of username, falling back to username when unset.

Also fixes long attack_procedure/expected_detection/suggested_text
text overflowing its container in the template review panels and
Red/Blue team fields (missing break-words on whitespace-pre-wrap
blocks).
2026-07-17 16:58:25 +02:00
kitos 60ab2e558f fix(campaigns,tests): admin cannot create campaigns, manager can delete unstarted tests, intensify red/blue team colors
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
- Campaign creation and generate-from-threat-actor now use the strict
  role check — admin no longer gets a free pass into campaign content,
  same principle already applied to test-template creation.
- New manager-only DELETE /tests/{id}: removes a standalone test still
  in draft (not started, not linked to any campaign).
- Replaced the orange/indigo stand-ins used across team badges, tabs,
  action buttons, and timers with true red/blue so Red Team and Blue
  Team read unambiguously at a glance.
2026-07-17 14:34:14 +02:00
kitos 4809c4a662 feat(manager): allow manager to create auto-approved campaigns and tests from templates
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
A manager organizes and validates work, so their own campaigns skip the
draft -> submit -> pending_approval queue and go straight to active with
the start_date they provide (they're the same role that would otherwise
approve it). Manager can also now create tests from the catalog, same as
red_lead/blue_lead.
2026-07-16 12:57:20 +02:00
kitos c753797019 feat(test-catalog): add template creation and lead-approval workflow
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Leads get a Create Template button that adds directly to the catalog
(existing POST /test-templates). Operators (red_tech/blue_tech) get the
same button, but their proposal now lands in a new template_suggestions
review queue instead — a lead on their team can approve it as-is, edit
fields before approving, or discard it. Modeled on the existing
ProcedureSuggestion review workflow.
2026-07-16 12:08:23 +02:00
kitos 0002601b50 feat(templates): add pagination with total counts to catalog and campaign picker
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Test Catalog's pagination showed only 'Page N' with no way to know
how many pages existed, and the campaign 'Add Test' modal's template
picker had no pagination at all — with 2800+ templates in the
catalog, its flat 100-row fetch made most templates unreachable
unless a search happened to match. Adds GET /test-templates/count
(open to any authenticated user, mirrors the list endpoint's filters)
and wires real 'Page N of M' + total-available counts into both.
2026-07-16 10:01:20 +02:00
kitos 3a01facd46 feat(tests): let managers escalate and directly resolve disputed tests
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Request Discussion only ever nudged the peer lead, and the one-time
manager notification when a dispute starts had no real follow-up
action attached to it — a manager could be told a dispute existed but
had no way to actually do anything about it. Adds:

- POST /tests/{id}/escalate-to-manager — either lead can explicitly
  ask managers to step in, distinct from the passive initial notice.
- POST /tests/{id}/manager-resolve-dispute — a manager decides the
  final outcome (validated/rejected) directly, bypassing both leads'
  votes entirely, reusing the same dual-validation event dispatch so
  Jira/notifications behave like any other resolution.

Both leads are notified of the manager's final call, win or lose.
2026-07-15 13:03:01 +02:00
kitos 8973f199b8 feat(tests): make Expected Detection editable when creating a test from template
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Leads can now edit Expected Detection in the create-from-template
form, same as Suggested Attack Procedure — the edit seeds the new
test's detect_procedure via a detect_procedure_override, without
touching the template itself. The template only updates later through
the existing procedure-suggestion approval flow, once a round is
actually submitted — same mechanism as the red side, no new bypass.
2026-07-15 11:05:41 +02:00
kitos 60f9464ec5 refactor(tests): merge detect_suggested_procedure into expected_detection
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Two overlapping TestTemplate fields (expected_detection: narrative
guidance from imports/leads; detect_suggested_procedure: concrete
commands from approved suggestions) are now one. Blue-side procedure
suggestions target expected_detection directly, appending onto
whatever is already there rather than overwriting it — same
merge-not-overwrite behavior already used for the red side. Existing
detect_suggested_procedure data is folded into expected_detection
before the column is dropped.
2026-07-15 10:29:13 +02:00
kitos 4692a8b93e feat(tests): add Detect Procedure UI, template suggested-procedure editing, lead review panel
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Blue Team gets a Detect Procedure textarea in the test detail view,
mirroring Red's Attack Procedure field. Template create/edit forms
gain a Detect Suggested Procedure field for leads to curate directly.
Leads also get a Procedure Suggestions panel on the Tests page,
scoped to their own team by the backend, to approve or reject
suggestions extracted from submitted rounds.
2026-07-14 15:30:47 +02:00
kitos 0fc2427f71 feat(review): review queue for leads + manual reviewer reassignment
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Leads get the same two-queue view operators already have: 'Available
to Review' (pending reviews currently assigned to a peer lead) and
'My Assigned Reviews' (assigned to me), replacing the old single
'My Reviews' toggle. Since the load-balanced auto-assignment always
picks a reviewer immediately, 'available' means peer-assigned reviews
a lead could pick up if the assignee can't get to them, not unclaimed
ones (there aren't any).

POST /tests/{id}/assign now also accepts red_reviewer_assignee /
blue_reviewer_assignee, validated against the matching lead role and
synced to Jira the same way operator assignment already is. The
AssigneeControl UI gained a 'reviewer' kind (leads-only picker) shown
on the test detail header while a test sits in red_review/blue_review
— this also fixes the reviewer assignment being invisible in Aegis
even though it was already being pushed to Jira correctly.
2026-07-10 16:19:14 +02:00
kitos 58c0143304 feat(permissions): admin no longer acts on the test workflow; managers coordinate operators
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Admin administers the site — it no longer has any override on
validate-red/blue, review-red/blue, resolve-dispute, request-discussion,
reopen, hold, resume, assign-operators, or classification-update.
Introduces require_any_role_strict(), a role dependency without the
global admin bypass, so these specific endpoints truly exclude admin
instead of only removing it from the (redundant) role tuple.

Managers gain the ability to assign red_tech/blue_tech operators
(POST /tests/{id}/assign, GET /users/operators) alongside leads, since
that's coordination, not resolving a ticket.

Also enlarges and repositions the operator-assignment controls next
to the Start Execution button, and fixes a literal '\u2014' rendering
as text instead of an em dash in the test detail technique line.
2026-07-10 10:28:04 +02:00
kitos 2afb886cd9 feat(assign): let leads manually assign operators + sync Jira; send platform as Jira label
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Adds GET /users/operators (leads+admin) and wires a lead-only assign
control into the test detail header, calling the existing but
previously unreachable POST /tests/{id}/assign endpoint. Manual
assignment now also pushes the Jira ticket assignee immediately
instead of waiting for the operator to start execution.

Also adds test.platform as a kebab-case label on Jira ticket creation.
2026-07-10 08:44:14 +02:00
kitos 8031682e9c feat(matrix): unify Techniques and Coverage Matrix into one page
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Techniques (/techniques) and Coverage Matrix (/matrix) showed the same
underlying data (Technique.status_global) with completely different
visual styles — discrete Tailwind status colors + ID+name cells on
Techniques, vs. a continuous score-gradient hex color + ID-only cells
(name via tooltip) on the heatmap. Coverage Matrix also has 3 layers
(Threat Actor, Detection Rules, Campaign) with no Techniques equivalent,
so Techniques was the strict subset — merged into Coverage Matrix rather
than the other way around.

- HeatmapCell now uses the same discrete status-color palette as the old
  TechniqueCell (cellColors.ts), shows the technique name inline, and
  keeps zoom/virtualization/hover-tooltip untouched.
- HeatmapLegend restyled to match (swatch + label + description per
  tier, review_required as an overlay badge) instead of the old
  hex-gradient bar.
- MatrixPage gains a Matrix/List view toggle and a status filter
  (coverage/threat-actor layers only) — both ported from the old
  Techniques page — so nothing it offered is lost.
- /techniques now redirects to /matrix; removed TechniquesPage,
  AttackMatrix, TechniqueCell (fully superseded). /techniques/:mitreId
  (detail) and /techniques/review-queue are untouched.

Known pre-existing limitation carried over, not introduced or fixed
here: the heatmap only places a multi-tactic technique under its first
tactic column (_format_tactic takes tactic_str.split(",")[0]), while the
old Techniques matrix placed it under every tactic it belongs to.
2026-07-09 14:19:38 +02:00
kitos 4e31359fca feat(frontend): add technique/platform/outcome/date filters to Validated Tests
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
The "200" badge on the Validated Tests page was a hardcoded query limit,
not the real total — silently hiding results beyond the 200th once there
were more validated tests than that. Now shows the true total via the new
/tests/count endpoint, and warns when the fetched page doesn't cover all
matches.

Adds filter controls beyond the existing name/technique text search:
technique (MITRE ID or name), platform, attack outcome, detection
outcome, and a validated-date range — all pushed down to the server via
the new GET /tests filters instead of only ever searching the current
page client-side.
2026-07-09 12:45:54 +02:00
kitos 8cf8001de5 feat(frontend): My Reviews queue, duplicate-test badge, tactic order, legend + tooltip fixes
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
- TestsPage gains a "My Reviews" toggle for red_lead/blue_lead, separate
  from "My Tasks" — filters by reviewer_id at the red_review/blue_review
  gate instead of the unrelated in_review validation stage
- Test Catalog cards now warn when a technique already has existing
  tests, using the backend's new existing_test_count
- ExecutiveDashboardPage drops its duplicate client-side tactic-order
  sort now that the backend returns canonical order; time-range filter
  now notes which sections it actually scopes
- HeatmapLegend adds the missing review_required swatch (as an overlay
  indicator, matching how it's actually rendered on cells) and hover
  tooltips reusing StatusBadge's copy instead of being unexplained
  static color chips
- Fix a real React key bug in ControlsTable: rows were grouped in a
  keyless shorthand fragment, which can misreconcile when the table is
  filtered/sorted; switched to a keyed Fragment
- Minor: CompliancePage summary-card grid no longer strands a lone card
  on tablet widths
2026-07-08 08:46:24 +02:00
kitos 1ddbd6989f fix(frontend): hide viewer-only risk-compute UI, proactively renew session
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
- Executive Dashboard no longer auto-triggers POST /risk/compute or shows
  the Refresh scores button for roles the backend rejects (viewer), which
  was causing a 403 on load
- AuthContext now proactively renews the session cookie every 20 minutes
  while the app is open, so an actively-used session doesn't rely solely
  on the reactive on-401 refresh racing against its own token's expiry
2026-07-07 13:42:54 +02:00
kitos c0a88fc489 feat(tests): attack_success 3-value UI, data classification badge, reorder containment options
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
2026-07-06 16:19:50 +02:00
kitos 19c4866103 feat(tests): dispute resolution UI — manager escalation + red/blue queue selector
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
2026-07-06 12:40:21 +02:00
kitos 82033b5037 feat(tests): types and API client for red/blue review workflow 2026-07-06 12:02:07 +02:00
kitos b106780102 fix(campaigns): drop dead force param from activateCampaign API client
The backend endpoint no longer accepts a force query param (a draft
campaign can never have a future start_date to force past). No frontend
code currently calls this function, but keep it matching the real
backend contract in case a future admin UI wires it up.
2026-07-04 12:02:10 +02:00
kitos 858dd3e9e7 docs(campaigns): explain why CampaignModificationRequest.test_id can be null 2026-07-04 12:02:10 +02:00
kitos 15ef555131 feat(campaigns): API client for approval workflow 2026-07-04 12:02:10 +02:00
kitos cef082d0c4 feat(tests): execution start/end times on red team, detection/containment times on blue team
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
2026-06-24 13:09:13 +02:00
kitos 2e45cf1be0 feat(tests): containment_result field on blue team evaluation
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
2026-06-24 12:35:19 +02:00
kitos 18695197e8 feat(jira): admin account replaces per-user tokens for all Jira/Tempo ops
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
- Single admin Jira account stored in system_configs (jira.admin_email, jira.admin_api_token)
- Admin Tempo token in system_configs (tempo.admin_token)
- get_admin_jira_client() + has_admin_jira_configured() replace per-user auth in all lifecycle hooks
- lookup_user_jira_account_id() auto-discovers each user's Atlassian accountId by email on login
- auto_log_test_worklog() now uses admin Tempo token and logs both red+blue team time
- Settings > Jira: admin credentials fields + test buttons moved to admin Jira tab
- Profile section simplified: jira_account_id shown read-only (auto-detected)
2026-06-24 09:15:35 +02:00
kitos bb8b9a6a72 feat(dashboard): time range filter for operational metrics (30d/90d/6m/1y/all)
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
2026-06-19 10:41:22 +02:00
kitos 4e1f35c250 feat(tests): on-hold button with reason modal, Jira comment + On Hold transition
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
2026-06-19 09:53:05 +02:00
kitos 6147f15238 feat(tests): operator assignment — two queues for techs, assign endpoint for leads
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
2026-06-19 09:07:39 +02:00
kitos a7725ba519 feat(sso): Azure AD / Entra ID SAML 2.0 integration
- sso_service: fix process_callback for Azure AD claim URIs (email, role)
  - Default role_attr to full Azure role claim URI
  - Fallback email resolution via Azure email claim URI + NameID
  - Username defaults to full email (prevents collision with local accounts)
  - User lookup also tries email field for existing local accounts
  - Logs warning when unknown role received from IdP

- frontend/api/sso.ts: new API module with getSsoStatus, getSsoConfig, updateSsoConfig

- LoginPage: redesigned for SSO-first flow
  - Shows Azure SSO button as primary when SSO enabled+configured
  - Local login collapsed under "Emergency admin access" section
  - Falls back to normal local login form when SSO is disabled

- SystemPage: new SsoConfigSection component (guided 5-step wizard)
  - Step 1: Copy SP Entity ID and ACS URL for IT team + metadata XML download
  - Step 2: Azure App Roles reference table (6 roles with exact values)
  - Step 3: Tenant ID field auto-fills idp_entity_id and idp_sso_url
  - Step 4: X.509 certificate paste field
  - Step 5: Attribute mapping pre-filled with Azure AD claim URIs
  - Enable/disable toggle + save
2026-06-08 13:48:36 +02:00
kitos e2861a08bc feat(evaluations): enrich eval tests with attack path, criteria and data sources
- Capture Step.Description (HTML stripped), step name/number, substep ref,
  criteria, and data sources from MITRE ATT&CK Evaluations API
- _aggregate_by_technique() now accumulates ALL occurrences per technique
  (multiple substep refs, criteria, step contexts) instead of keeping only
  the best-scoring one
- New helper functions _build_procedure_text(), _build_description(),
  _build_red_summary() generate rich narratives from accumulated occurrences
- New re_enrich_evaluation_round() service function + POST endpoint
  /system/attck-evaluations/re-enrich to update already-imported tests
  without changing detection results or validation state
- Frontend: Re-enrich button per imported round + result banner in SystemPage
2026-06-08 11:42:08 +02:00
kitos b630cd3210 feat(evaluations): bulk approve evaluation tests with 4-step confirmation modal
Backend:
- POST /system/attck-evaluations/bulk-approve: finds all [EVAL R*] tests in
  in_review state, approves blue side, transitions to validated, recalculates
  technique statuses, audit logs each test
- GET /system/attck-evaluations/pending-count: returns count of pending eval tests

Frontend:
- BulkApproveModal: 4 mandatory checkboxes before confirm button enables
  (lab env / not org detection / metrics impact / spot-check recommendation)
- Bulk Approve button in header badge showing pending count
- Green result banner showing approved tests + techniques recalculated
- Invalidates techniques, metrics and review-queue queries on success
2026-06-05 16:53:00 +02:00
kitos 8515b8de17 fix(evaluations): bypass Cloudflare 403 with browser headers + hardcoded fallback rounds
- Add browser User-Agent and Referer headers to all evals.mitre.org requests
- fetch_rounds_with_status() returns api_reachable flag + rounds list
- Fallback to 5 known public CrowdStrike rounds (APT29/R2 through OilRig/R6)
  when live API is blocked, so UI always shows something actionable
- Router returns {rounds, api_reachable, api_error} instead of plain array
- Frontend shows orange warning banner when using fallback data
- Remove 502 HTTPException - rounds are always returned (live or fallback)
2026-06-05 16:10:27 +02:00
kitos b037500b7c feat(evaluations): ATT&CK Evaluations importer for CrowdStrike Falcon [FASE-6.1]
- Migration b048: evaluation_imports table (adversary, round, status, tests_created)
- EvaluationImport SQLAlchemy model
- attck_evaluations_service: fetch rounds from evals.mitre.org API, import per-technique
  detection results (Technique/Tactic/Telemetry -> detected/partially/not_detected)
- All imported tests land in in_review state with lab-environment disclaimer
- Idempotency guard prevents duplicate round imports
- 4 new endpoints: list rounds, import specific, import latest, check-new
- Weekly APScheduler cron (Mon 06:00) auto-checks and imports new rounds
- SystemPage UI: rounds table, import buttons, check-new, result feedback
- Disclaimer callout reminding admins these are lab results not org coverage
2026-06-05 15:57:03 +02:00
kitos 5f54396cb6 feat(rt-import): require base64 evidence images per technique
Each technique in the RT import JSON now requires at least one evidence
image (PNG/JPG/GIF/WebP/BMP, max 10 MB decoded) embedded as base64.

Backend:
- RTEvidenceEntry model: filename, data (base64), caption (optional)
- RTTechniqueEntry.evidence is now required
- Pre-validation raises 422 if any technique is missing evidence
- After test creation, images are decoded and stored in MinIO as
  Evidence records (team=red) linked to the test

Frontend:
- RTEvidenceEntry type added to api/tests.ts
- parseJson() validates evidence presence and structure per technique
- Preview table shows base64 thumbnails (up to 3 + overflow count)
- Format reference updated: evidence fields moved to Required section
- Import result shows total evidence images attached
2026-06-05 12:57:22 +02:00
kitos 564eb406aa fix(campaigns): fix start_date modal — interceptor was losing structured detail
client.ts: when FastAPI detail is an object, extract .message for the error
string and preserve the full detail on enhancedError.detail so consumers
can inspect structured error payloads (e.g. 409 start_date_in_future).

CampaignDetailPage: use enhancedErr.status (not response.status) and
enhancedErr.detail (not response.data.detail) to detect 409 and show
the confirmation modal instead of the toast.
2026-06-04 16:22:17 +02:00
kitos 6b1f5d690a fix(campaigns): start_date modal + hide future-campaign tests from queue
Backend: activate endpoint returns 409 with structured warning when
start_date is in the future; accepts force=true to bypass.
test_crud_service: always excludes tests from draft campaigns with future
start_date so they do not appear in the team queue prematurely.

Frontend: catches 409 on activate and shows amber confirmation modal
with Keep scheduled / Activate now anyway options.
2026-06-04 14:05:58 +02:00
kitos 27c67a5f76 feat(campaigns): start_date for threat-actor-generated campaigns
Backend:
- campaign_service.generate_campaign_from_threat_actor: accept optional
  start_date kwarg and set it on the Campaign model
- campaigns router: new GenerateFromActorPayload schema, /from-threat-actor
  endpoint now accepts optional body with start_date

Frontend:
- generateCampaignFromThreatActor API: accept optional options param
- Generate Campaign modal: date picker + warning message, same UX as the
  manual create form
2026-06-04 13:37:40 +02:00
kitos 92e8ff7aff feat(campaigns): campaign start date — scheduled activation, Jira start_date
DB: migration b047 adds start_date (DateTime nullable) + index to campaigns.

Backend:
- Campaign model: start_date field
- CampaignCreate/Update schemas: accept start_date (ISO string)
- CRUD service: persist + serialize start_date in both serializers
- Activation endpoint: blocks manual activation if start_date is in the future
  (campaign will auto-activate via scheduler)
- Scheduler: new hourly job _run_scheduled_campaign_activation — finds draft
  campaigns with start_date <= now, activates them, creates Jira tickets,
  notifies red_tech team
- Jira: campaign + test tickets now include JIRA_START_DATE_FIELD (configurable,
  default customfield_10015). Campaign uses start_date if set, else created_at.
  Tests inherit campaign start_date.
- config.py: JIRA_START_DATE_FIELD setting

Frontend:
- Campaign type: start_date field on Campaign + CampaignSummary
- CampaignCreatePayload: start_date optional field
- Create form: date picker with min=today, warning message explaining behavior
- Campaign detail header: start_date badge showing days remaining or started date
2026-06-03 16:57:06 +02:00
kitos 80991b2f59 feat(compliance): executive descriptions and mapping rationale for all 5 frameworks
Backend: expose description in control status response, add rich business-language
descriptions to all curated controls (ISO 27001, ISO 42001, CIS v8, DORA) explaining
requirements and ATT&CK mapping rationale. ISO 42001 includes infrastructure-mapping note.

Frontend: description field in type, info panel in ControlsTable expanded rows,
framework info banner with description and official standard link in CompliancePage.
2026-06-03 16:28:16 +02:00
kitos 200ef88d67 feat(compliance): add ISO/IEC 27001:2022 and ISO/IEC 42001:2023 frameworks
ISO 27001:2022: 37 Annex A controls across 4 themes (Organizational,
People, Physical, Technological) mapped to MITRE ATT&CK techniques.

ISO 42001:2023: 25 Annex A controls for AI Management Systems mapped to
relevant ATT&CK techniques covering AI supply chain, data pipeline
integrity, model serving security, and third-party AI risk.

Backend: import functions, _import_curated_framework() shared helper,
and POST /compliance/import/iso-27001 + iso-42001 endpoints.
Frontend: API client functions + import buttons in CompliancePage.
2026-06-03 15:50:54 +02:00
kitos 3b552dbe4e fix(disputed): add admin role + contact info in discussion modal
- request-discussion endpoint: add 'admin' to allowed roles
- Return rejector_email and rejector_role in the response
- Modal success state shows contact card with username, role, email link
  so the approving lead can immediately reach out to the rejecting lead
2026-06-03 13:02:57 +02:00
kitos 2ecb950770 feat(disputed): Confirm My Validation button + discussion request modal
Backend: POST /tests/{id}/request-discussion
  - Only callable by the lead whose vote is 'approved' in a disputed test
  - Sends notification to the rejecting lead: 'Lead X confirms their
    approval and wants to discuss your rejection'
  - Logs the action in audit trail

Frontend:
- 'Confirm My Validation' button (amber outline) alongside 'Change to Rejected'
- Opens a modal showing:
    * Explanation: both leads must agree to finalise
    * Other lead's rejection reason/notes
    * What happens next (stays disputed, notification sent, either can change)
- 'Send Discussion Request' → calls the new endpoint → shows success state:
    'Lead username has been notified...'
- Instruction to reach out via team channels to resolve offline

Flow summary for disputed tests:
  Approving lead sees 2 options:
    a) 'Confirm My Validation' → modal → send request → other lead notified
    b) 'Change to Rejected' → validation modal → both agree to reject → rejected
2026-06-03 12:48:08 +02:00
kitos f3c07fdaf1 fix(types): add conversion_rate fields to ValidationThroughput interface 2026-06-03 10:07:49 +02:00
kitos 31c644d23f fix(auth): silent token refresh — active sessions no longer expire mid-use
Problem: 15-minute tokens with no refresh mechanism kicked users to login
even when actively using the app.

Fixes:
1. config.py: raise ACCESS_TOKEN_EXPIRE_MINUTES from 15 → 480 (8h).
   Reasonable for an enterprise internal tool; still configurable via env.

2. POST /auth/refresh: new endpoint that reads the current aegis_token
   cookie and issues a fresh token if the session is still valid. Returns
   the new token in the cookie + body (same shape as /auth/login).

3. frontend/api/client.ts: response interceptor now attempts a silent
   refresh on 401 before redirecting to login:
   - Calls POST /auth/refresh once per failed request
   - If refresh succeeds: retries the original request transparently
   - If refresh fails: redirects to /login as before
   - Deduplicates concurrent refresh attempts (refresh once, resolve all)
   - Never attempts refresh on /auth/refresh or /auth/login themselves
2026-06-02 15:54:15 +02:00
kitos b438dd0af0 feat(campaigns): campaign timing panel with Red/Blue aggregated metrics
Backend: GET /campaigns/{id}/timing-summary
  Aggregates timing across all campaign tests:
  - red_execution_secs: red_started_at → blue_started_at (minus paused)
  - blue_queue_secs:    blue_started_at → blue_work_started_at
  - blue_evaluation_secs: blue_work_started_at → validated (minus paused)
  - total_secs: sum of all three phases
  Returns totals + per-test breakdown sorted by total time desc.

Frontend: new CampaignTimingPanel component replaces WorklogTimeline
  - 4 summary cards: Red Execution / Blue Queue / Blue Evaluation / Total
  - Stacked horizontal bar showing time distribution
  - Per-test breakdown with individual mini-bars and phase durations
  - Shows 'No tests started yet' when no timing data available
2026-06-02 11:06:42 +02:00
kitos 6021f0801c feat(rt-import): import Red Team engagement results as validated tests
Backend — POST /tests/import-rt (red_lead + admin):
  Accepts engagement JSON with name/date/description/operator and
  a list of techniques each with mitre_id, result, attack_success,
  platform, notes. Creates one Test per technique directly in
  'validated' state (red + blue validation = approved) bypassing
  the normal workflow. Recalculates technique.status_global for
  all affected techniques. Returns created/skipped summary.

Frontend — /tests/import-rt (new dedicated page):
  - Format reference panel (collapsible) with field descriptions
  - Download template JSON button (generates a filled example)
  - Paste JSON textarea + file upload (.json)
  - Live validation + preview table showing what will be imported
  - Import button with spinner
  - Success / warning / error result display
  Accessible to admin and red_lead only.
  Added to sidebar under Tests > Import RT Results.
2026-05-29 16:15:35 +02:00