plugins/power-pages/skills/manage-headers/SKILL.md
Inspects and configures the security headers a Power Pages site sends to browsers — Content Security Policy, frame and clickjacking protection, cross-origin sharing, cookie behavior, and related site settings. Identifies gaps and walks the user through fixes. Use when the user wants to review headers, fix CSP errors, allow embedding in another site, control cross-origin access, harden cookie settings, or asks "are my browser settings safe?", "fix my CSP", "set up CORS" — even if they only mention a specific header name without saying "security headers".
npx skillsauth add microsoft/power-platform-skills manage-headersInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Plugin check: Run
node "${CLAUDE_PLUGIN_ROOT}/scripts/check-version.js"— if it outputs a message, show it to the user before proceeding.
Inspect and configure the HTTP security headers for a Power Pages site. Headers are configured as HTTP/* site settings stored in .powerpages-site/site-settings/ YAML files.
Initial request: $ARGUMENTS
.yml file in .powerpages-site/site-settings/. The file name uses - instead of / (e.g., HTTP/X-Frame-Options → http-x-frame-options.sitesetting.yml).HTTP/Strict-Transport-Security — the runtime does not recognize it and the setting has no effect.HTTP/* header emission. Verify headers in an incognito tab, not the studio preview.script-src contains 'nonce', the runtime replaces it per-request with 'nonce-<random>' and auto-hashes inline event handlers. Scripts created dynamically via document.createElement do NOT receive the nonce.SameSite=None requires HTTPS. The runtime sets Secure on every cookie over HTTPS automatically.* is auto-specialized. The runtime replaces * per-request with the specific requesting Origin — the browser sees a single-origin header, not a wildcard.Create tasks in four groups. Mark each in_progress when starting, completed when done.
| Group | When to create | Tasks | |-------|----------------|-------| | 1 | At start | Check prerequisites | | 2 | After prerequisites pass | Inspect current headers · Assess and plan (skip "Assess and plan" in review mode) | | 3 | After user approves changes | Apply changes (skip in review mode OR if no changes were accepted) | | 4 | After apply or assess | Summarize (always) |
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.
Check that .powerpages-site/site-settings/ exists. If not, the site has not been deployed yet — tell the user and recommend /deploy-site. Stop.
Use Glob to find all *.yml files in .powerpages-site/site-settings/. Use Read to read each file and extract the name and value fields. Identify all settings with an HTTP/ prefix — these are the configured headers.
Compare against the recognized header catalogue in references/headers-reference.md. For each header in the catalogue:
For CSP specifically: if HTTP/Content-Security-Policy is present, scan the project's source files using Glob + Read to find external URLs and check whether they are covered by the policy. Identify the site's cloud environment via pac auth who to determine the correct Power Pages runtime host (see headers-reference.md § "Power-Pages-runtime sources a CSP must allow").
Skip in review mode.
MUST use plain language only. Never lead with words like CSP, CORS, HSTS, or MIME sniffing — explain using everyday language:
| Header concept | Plain-language name | |----------------|---------------------| | Content-Security-Policy | "which scripts and resources the browser is allowed to load" | | X-Frame-Options / frame-ancestors | "whether other websites can put your site inside a frame" | | X-Content-Type-Options | "stop the browser from guessing file types" | | CORS headers | "which other websites can call your site's data" | | SameSite cookies | "when the browser sends your sign-in cookie" |
Read references/headers-reference.md for recommended values and guidance. Present the most important gaps first — headers that are missing or misconfigured relative to the recommended values.
For each finding, present via AskUserQuestion:
Do NOT present all headers at once — present the important gaps first. For headers already set to recommended values, mention them in the summary without requiring action.
When the user needs a CSP (missing or incomplete), compose one using:
'nonce' keyword for inline scriptsWhen reviewing an existing CSP, validate:
Present the composed or corrected CSP for review. Recommend starting in report-only mode (HTTP/Content-Security-Policy-Report-Only) before enforcing.
Skip in review mode.
For existing settings: use Edit on the YAML file directly — change the value field.
For new settings: use the shared create script:
node "${CLAUDE_PLUGIN_ROOT}/scripts/create-site-setting.js" \
--projectRoot "<PROJECT_ROOT>" \
--name "<setting-name>" \
--value "<value>" \
--description "<description>"
See references/commands.md for details.
After all changes are applied, offer to deploy: "Ready to deploy these changes? They take effect after the next deploy." If yes, invoke /deploy-site.
First, read the configured HTTP/* site settings (from Step 2 — you already have them). Then write <REVIEW_DIR>/header-annotations.json with a plain-language description for each header and, when the configured value has a genuine issue (missing critical directive, weak value), a suggested fix. The transform script no longer hardcodes header descriptions — they come from you.
{
"headers": {
"HTTP/<HeaderName>": { "description": "What this header does, in plain language.", "fix": "Optional fix if the configured value has a genuine issue." }
}
}
Use references/headers-reference.md for authoritative descriptions and validation rules. Surface a fix only when the value has a real problem — do not editorialize on every header.
Then run the transform:
node "${CLAUDE_PLUGIN_ROOT}/skills/manage-headers/scripts/transform-headers.js" \
--projectRoot "<PROJECT_ROOT>" \
--annotations "<REVIEW_DIR>/header-annotations.json"
Write the stdout to <REVIEW_DIR>/manage-headers.json and stop. The transform emits { status, findings, details }; the orchestrating skill handles presentation.
Skip in review mode.
Plain-language summary: what was changed, what gaps remain, and what is already well-configured.
Reference:
${CLAUDE_PLUGIN_ROOT}/references/skill-tracking-reference.mdUse
--skillName "ManageHeaders".
If a natural follow-up exists based on findings, suggest it. If no meaningful follow-up exists, end the skill.
cross-origin when unsure.preview only on options that modify a setting value. Do not add to informational choices.https: wildcards in CSP directives — list specific hosts instead./deploy-site after applying changes.references/headers-reference.md — recognized header catalogue, recommended values, CSP composition rules, runtime sources. Read before Step 2 (inspect) and Step 3 (assess) in interactive mode.references/commands.md — shared create-site-setting.js usage. Read at Step 4 (apply) when creating new settings.tools
Configure the Canvas Authoring MCP server for the current coauthoring session. USE WHEN "configure MCP", "set up MCP server", "MCP not working", "connect Canvas Apps MCP", "canvas-authoring not available", "MCP not configured", "set up canvas apps". DO NOT USE WHEN prerequisites are missing — direct the user to install .NET 10 SDK first.
development
Use when the user asks to "set up authentication", "add login", "add logout", "add sign in", "enable auth", "add role-based access", "add authorization", "protect routes", "configure identity provider", "configure Entra ID", "configure Entra External ID", "configure OpenID Connect", "add OIDC", "set up SAML", "set up WS-Federation", "set up local login", "add username password", "add Facebook login", "add Google sign in", "add Microsoft Account", "set up invitation login", or otherwise wants to set up authentication (login/logout) and role-based authorization for their Power Pages code site using any supported identity provider (Microsoft Entra ID, Entra External ID, OpenID Connect, SAML2, WS-Federation, local authentication, Microsoft Account, Facebook, or Google).
development
Creates, updates, and deploys Power Apps generative pages for model-driven apps using React v17, TypeScript, and Fluent UI V9. Orchestrates specialist agents for planning, entity creation, and code generation. Use it when user asks to build, retrieve, or update a page in an existing Microsoft Power Apps model-driven app. Use it when user mentions "generative page", "page in a model-driven", or "genux".
development
Creates a new Power Pages code site (SPA) using React, Angular, Vue, or Astro. Guides through the full process from initial concept to deployed site: requirements discovery, scaffolding, component planning, design, implementation, validation, and deployment. Use when the user wants to create, build, or scaffold a new Power Pages website or portal.