Skip to content

feat(bigip): surface the three AWAF forms + honest declines in the console & report - #54

Merged
henleda merged 1 commit into
mainfrom
feat-bigip-console-report-surface
Aug 18, 2026
Merged

feat(bigip): surface the three AWAF forms + honest declines in the console & report#54
henleda merged 1 commit into
mainfrom
feat-bigip-console-report-surface

Conversation

@henleda

@henleda henleda commented Aug 18, 2026

Copy link
Copy Markdown
Owner

What & why

Task A of the BIG-IP resume: the console ④ Mitigate "Apply on your own BIG-IP" panel (PRs #47#48) and the standalone report predate waf_data_guard and api_schema, so they didn't reflect the current forms. The backend was already correctapply_bigip dispatches through emit(target="bigip-awaf") and handles all three shipped forms while honestly declining the rest — so this is a purely presentational fix. Offline throughout (no lab).

Audit findings (all verified before changing anything)

Console panel — dropdown hardcoded to service_policy (index.html:638), so waf_data_guard/api_schema findings were unreachable and no decline was ever surfaced. Help text said "Only service_policy band-aids have an AWAF form today" (stale).

Report — no BIG-IP surface at all, and a verified crash: a BIG-IP apply wrote before_after as a [before, after] list (bigip_apply.py:205) while every XC apply writes a {before, after} dict; the report does ba.get("before"), so building a report after any BIG-IP apply raised AttributeError: 'list' object has no attribute 'get'. (export.py:142 already guarded this shape and silently dropped it.)

Changes

Console

  • "Apply on your own BIG-IP" dropdown now driven by /api/emit (target bigip-awaf) — the emitter is the source of truth, so all three forms are selectable and every declining control is listed inline with its reason. Help text rewritten.
  • Refreshed the ② Review "Emit for another WAF" copy to name all three forms + the waf staging decline.

Report

  • Root-caused the before_after list→dict inconsistency in bigip_apply.py (fixes the crash + the export drop). _impact_rows also normalizes the legacy list shape so reports over pre-fix audit logs still render.
  • New "BIG-IP Advanced WAF (bring-your-own)" section, computed per-finding from the same emitter over the run's policies.json + probes.json: names the form emitted for each finding, and splits declines into "no Advanced-WAF object at all" (XC-only, structural) vs "form exists but this finding lacked the data". No fabricated "supported" states.
  • apply_bigip_awaf now labelled in the impact table.

emitters.pyAWAF_FORMS registry (form names in one place, read by the report) + shared WAF_STAGING_REASON constant.

Tests

+7 tests (emitter registry↔emit consistency, report BIG-IP section + decline split, the crash regression + legacy-list tolerance, the /api/emit panel contract). Full suite 1126 pass, 15 skipped, ruff clean.

🤖 Generated with Claude Code

…nsole & report

The BIG-IP backend (apply_bigip → emit(target="bigip-awaf")) already handles all
three shipped forms (service_policy, waf_data_guard, api_schema) and honestly
declines the rest, but two presentational surfaces predated waf_data_guard and
api_schema and misrepresented the state:

Console ④ Mitigate "Apply on your own BIG-IP" panel
- Dropdown was hardcoded to service_policy findings only, so 2 of 3 shipped forms
  were unreachable and no decline was ever shown. Now driven by /api/emit
  (target=bigip-awaf) — every shipped form is selectable and every declining
  control is listed inline with its reason. Help text rewritten (was "Only
  service_policy … has an AWAF form today").
- Refreshed the ② Review "Emit for another WAF" copy to name all three forms +
  the waf staging decline.

Standalone report
- FIX (verified crash): a BIG-IP apply wrote before_after as a [before, after]
  list while every XC apply writes a {before, after} dict, so building a report
  after any "Apply on your own BIG-IP" run raised AttributeError on ba.get().
  Root-caused in bigip_apply.py (now the dict shape); export.py's silent drop is
  fixed too. _impact_rows also normalizes the legacy list shape so reports over
  pre-fix audit logs still render.
- New "BIG-IP Advanced WAF (bring-your-own)" section, computed per-finding from
  the SAME emitter over the run's policies.json + probes.json: names the form
  emitted for each finding, and splits declines into "no AWAF object at all"
  (XC-only, structural) vs "form exists but this finding lacked the data". No
  fabricated "supported" states.
- apply_bigip_awaf now labelled in the impact table.

emitters.py: AWAF_FORMS registry (form names, one place) + WAF_STAGING_REASON
constant shared by emit and the legends.

+7 tests. Full suite 1126 pass, ruff clean. Offline throughout — no lab.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@henleda
henleda merged commit 9101558 into main Aug 18, 2026
4 checks passed
@henleda
henleda deleted the feat-bigip-console-report-surface branch August 19, 2026 02:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant