manage-firewall

Inspects and configures the web application firewall (WAF) in front of a Power Pages production site. Lists the current state, recommends enabling protection when it is off, and walks the user through adding, updating, or removing custom rules — IP blocks, country blocks, path blocks, and rate limits. Use when the user wants to turn on WAF, block traffic by IP or country, rate-limit login or signup pages, protect pages from brute-force attempts, restrict access to specific paths, review the current firewall configuration, or asks "is my site protected against bots / common web attacks?" — even if they say "add rate limit" or "protect login page" without mentioning "firewall" or "WAF".

Provider: Microsoft Power Platform APIs Path in repo: plugins/power-pages/skills/manage-firewall/SKILL.md

Skill body

Plugin check: Run node "${CLAUDE_PLUGIN_ROOT}/scripts/check-version.js" — if it outputs a message, show it to the user before proceeding.

Manage Web Application Firewall

Configure the firewall for a Power Pages production site. The firewall is only available on production sites and in supported regions — the scripts detect and report eligibility issues. After rule changes, edge propagation takes up to one hour.

Initial request: $ARGUMENTS

Gotchas

Workflow

  1. Prerequisites — Locate project, confirm sign-in, identify site, check eligibility
  2. Check firewall state — Capture status and rules
  3. Choose an action — Context-aware recommendation or question
  4. Apply the change — Run the matching script, verify
  5. Summarize and next steps — Present result, record usage, offer follow-ups

Task Tracking

Create tasks in three groups. Mark each in_progress when starting, completed when done.

Group When to create Tasks
1 At start Check prerequisites
2 After prerequisites pass Check firewall state · Choose an action (skip in review mode)
3 After user confirms an action Apply the change (skip in review mode OR no change action was chosen) · Summarize and next steps (always)

1. Prerequisites

1.1 Locate the project, detect review mode

Use Glob to find **/powerpages.config.json. If $ARGUMENTS contains --review <out-dir>, remember the output directory — Steps 3–4 are skipped and Step 5 writes JSON only.

1.2 Resolve site identifiers

Read .powerpages-site/website.yml → extract id field → that is <WEBSITE_ID>.

If missing, the site has not been deployed. Tell the user and recommend /deploy-site. Stop. Do not resolve by name or URL.

Resolve to portalId:

node "${CLAUDE_PLUGIN_ROOT}/scripts/website.js" --websiteId "<WEBSITE_ID>"

Capture Id (portalId), Type, Name, WebsiteUrl. If exit code 2 → sign-in required (pac auth create or az login). If null → site not found in this environment. Stop in either case.

1.3 Eligibility

Check the Type field and the script responses for eligibility. The scripts return specific error codes for ineligible sites (non-production, unsupported region, restricted feature). Read references/commands.md § “Common error catalogue” and § “Regional availability” for the full list.

If the site is ineligible, tell the user in plain language what the limitation is and stop.


2. Check firewall state

2.1 Get status (always run first)

node "${CLAUDE_PLUGIN_ROOT}/skills/manage-firewall/scripts/get-status.js" --portalId "<PORTAL_ID>"

The response shape is { "status": "ok", "value": "<state>" }.

If the status response is "status": "unsupported", tell the user the firewall is not available and stop.

2.2 Get rules (only when WAF is enabled)

node "${CLAUDE_PLUGIN_ROOT}/skills/manage-firewall/scripts/get-rules.js" --portalId "<PORTAL_ID>"

Both scripts output the full response as JSON to stdout. If get-rules.js returns "status": "unsupported", tell the user the firewall is not available and stop.


3. Choose an action

Skip in review mode.

MUST use plain language only with the user. Never use words like WAF, OWASP, ModSec, ruleset, geo-block, rate-limit, ASN, SocketAddr, or rule priority.

Each AskUserQuestion call is a separate call. Wait for the user’s answer before asking the next.

Default approach

Analyze the site’s current state (firewall status, existing custom rules, managed rules, region eligibility) and recommend the single most relevant action. Present the recommendation with a plain-language explanation of why. The user can accept, choose a different action, or ask to just view the current state.

If the site’s state does not warrant a specific recommendation, do not force one — ask what the user wants to do.

MUST NOT proactively offer actions that reduce security (disabling the firewall, removing managed rules, weakening existing rules). If the user needs those, they will ask.

Option rules

When presenting options via AskUserQuestion:

Rule type follow-up

When the user picks “Add a rule”, ask a follow-up for the rule type. The same option rules apply. Translate the answer into set-rules.js parameters — keep the user out of priority-numbering and rule-naming details. Read references/rule-reference.md for rule shapes.

Remove a rule

List current custom rules showing: what each rule does (plain language), what traffic it matches, whether it blocks or allows, and its priority relative to others. If removing a rule would break a deny/allow pattern, warn before proceeding.

Plan-validate-execute

For all rule changes:

  1. Plan — build the JSON payload containing only the rules being added or updated.
  2. Validate — check the plan against the existing rule set and surface:
    • Priority conflicts with existing rules
    • Overlapping match conditions (same matchVariable/operator, overlapping matchValue) — explain which rule wins via first-match-wins
    • Contradictions between Allow and Block rules — flag and explain priority implications
    • Redundancy — suggest updating the existing rule instead of adding a duplicate
  3. Execute — apply only after user approval.

For deletions, show the rule names and what each currently does before proceeding.

In review mode, skip this step entirely.


4. Apply the change

Skip in review mode.

Action Script
Enable enable.js --portalId <id>
Disable disable.js --portalId <id>
Add / update rules set-rules.js --portalId <id> --data-inline '<json>'
Remove rules delete-rules.js --portalId <id> --names <comma-separated>

Run enable/disable with run_in_background: true (async operations with built-in polling).

Before applying, show only the disclosure relevant to the action being taken:

After completion, re-run status and rules calls to verify the new state.


5. Summarize and next steps

5.1 Review mode

Apply the same status-then-rules gating as § 2 — get-rules.js MUST only be invoked when the status value is Created. For any other value the WAF policy does not exist and the rules endpoint will return 500; the orchestrator must write the empty-rules payload directly instead of calling the script.

Step A — always run status:

node "${CLAUDE_PLUGIN_ROOT}/skills/manage-firewall/scripts/get-status.js" --portalId "<PORTAL_ID>" > "<REVIEW_DIR>/firewall-status.json"

Step B — branch on the captured value:

After capturing the raw output, read both files and write <REVIEW_DIR>/firewall-annotations.json with plain-language descriptions of the state and each rule (the transform script no longer hardcodes these — they come from you):

{
  "state": {
    "description": "Plain-language explanation of what \"<value>\" means — is the firewall actively filtering requests, or not?",
    "fix": "Optional — include only if the state genuinely needs action."
  },
  "rules": {
    "<RuleName>": { "description": "What this rule does, in plain language.", "fix": "Optional fix if the rule has a genuine issue." }
  }
}

Power Pages WAF state semantics (use these when writing the state description — do not invent meanings):

Then run the transform:

node "${CLAUDE_PLUGIN_ROOT}/skills/manage-firewall/scripts/transform-firewall.js" \
  --statusFile "<REVIEW_DIR>/firewall-status.json" \
  --rulesFile  "<REVIEW_DIR>/firewall-rules.json" \
  --annotations "<REVIEW_DIR>/firewall-annotations.json"

Write the transform stdout to <REVIEW_DIR>/manage-firewall.json and stop. The transform emits { status, findings }; the orchestrating skill handles presentation.

5.2 Present summary

Plain-language summary: firewall on/off, rule count, what changed, important gaps.

5.3 Record skill usage

Reference: ${CLAUDE_PLUGIN_ROOT}/references/skill-tracking-reference.md

Use --skillName "ManageFirewall".

5.4 Offer follow-ups

If a natural follow-up action exists based on the site’s verified post-action state, suggest it. Do not offer actions that reduce security. If no meaningful follow-up exists, end the skill — do not ask just to ask.


Constraints

References

Skill frontmatter

user-invocable: true argument-hint: [optional: --review ] allowed-tools: Read, Write, Bash, Glob, Grep, AskUserQuestion, TaskCreate, TaskUpdate, TaskList model: opus