·
Last changedVersion:
This version passed the hardening gate. Hardening applied 21 targeted changes, deleted the lines high-severity poisoning findings flagged in 1 file before any model saw the skill, and preserved all other text. Classified findings before hardening: 7. Classified findings closed: 3. Classified findings remaining: 4. Unclassified scanner findings remaining: 0. Review findings closed: 17. Review findings remaining: 1.
1
4
2
2
2
Expand | File | Group | Subtype | Severity | Status |
|---|---|---|---|---|---|
scripts/impersonate-audit.sh | Sensitive Data & Secret Exposure | Agent snooping | High | Closed | |
SKILL.md | Tool & MCP Manipulation | MCP configuration abuse | Medium | Open | |
README.md | Excessive Agency & Rogue Autonomy | — | Medium | Open | |
README.md | Supply Chain & Install-Time Trust | — | Medium | Closed | |
scripts/impersonate-audit.sh | Supply Chain & Install-Time Trust | — | Medium | Closed | |
README.md | Malicious Code & Command Execution | — | Low | Open | |
README.md | Supply Chain & Install-Time Trust | Install-time download and execute | Low | Open |
7 findings
Verify that a customer's experiment is actually collecting variant data, that downstream attribution survives the funnel, and that the metrics measure what the customer thinks they measure. Output is a Slack-ready writeup grouped by the four questions customers almost always ask.
The skill assumes the active PostHog MCP is scoped to the customer's project, not yours. Always start with:
If the project name looks like your own internal project (e.g. "PostHog App + Website", id 2), STOP — the impersonation isn't routing correctly. Ask the human operator to check /mcp auth before continuing; the operator runs that step, not the agent.
Before any other query, ask the operator to name the expected customer organization and project id. Compare them with what the MCP reports. Continue only on an exact match that the operator then confirms; on any mismatch or missing answer, STOP and report it. Stay in that project for the whole audit and ask the operator before switching projects.
Confirm with the operator that they hold valid staff authorization for this impersonation before Step 1.
Use experiment-list with search to find the experiment by name. Then pull the full record. Capture:
device_id vs user_id), and ensure_experience_continuity.$feature_flag_called or a custom event.For the linked flag:
$current_url = ...) — uses the latest URL the person has been seen on, not the current page. Stale by definition. Always flag as a problem.$current_url is captured as the full URL (https://host/path). Exact-matching /path will never hit.ensure_experience_continuity setting on the flag (this overrides the experiment-level setting).Pull $feature_flag_called events for the flag key since the experiment start date.
$feature_flag_response. Should split close to 50/50 between the variant names (e.g. control / test). Flag a sample ratio mismatch if imbalance exceeds ~5% with non-trivial volume.$feature_flag_response returns false for most events, the user isn't being bucketed into the experiment at all — the release condition is rejecting them. This is the most common cause of "experiment shows 0 exposures."$current_url, $device_type, $feature_flag, $feature_flag_response, and distinct_id. Keep these raw values in your working notes; the report uses masked ids and URLs with query strings removed.For each metric event (CTA click, signup page visit, signup completion, conversion):
$feature/<flag-key> property with a real variant value (control or test), not false or missing.$pageview containing /signup"), it will credit both variants for global traffic regardless of source. Suggest scoping by $feature/<flag-key> property or session entry pathname.Cross-domain handoff (Webflow → app, marketing → product, etc.) is where attribution usually dies.
$feature_flag_called event with a real variant value.$identify fires on the handoff. If users never have an $identify event, the anonymous device profile never stitches to the authenticated user — variant attribution is dead even with a perfectly fired flag.ensure_experience_continuity settings together don't cause re-bucketing. device_id bucketing without continuity = same user on a new device looks fresh.Customers often have a primary conversion event that lives downstream (in their app or warehouse).
plus_trial_activated, trial_started, subscription_created).external-data-sources-list. Common pattern: Snowflake/Postgres table like accounts.trial_started_at. Limit this to source and table names; leave connection details unread, and run row-level warehouse queries only when the customer explicitly asks.The customer's actual setup almost always has one of these:
$identify on the marketing → product domain handoffdevice_id bucketing without ensure_experience_continuity → re-bucketing across sessionsGroup the report by the four standard customer questions. Lead with the worst finding:
Remind the user to complete every step below (these are operator steps; the agent leaves them to the human):
claude plugin disable posthog/mcp, clear the posthog authentication so the impersonation token is dropped, then confirm the logout and the disable before starting another taskThe impersonate-audit.sh wrapper (shipped in this plugin as scripts/impersonate-audit.sh) handles step 3 prompts on exit.
Get started with chainctlchainctl skill install public/posthog/impersonation-toolkit:latest
Bring Chainguard's hardening pipeline to your first-party skills — custom rulesets, automated remediation, full audit trail.
skills.cgr.dev/public/github.com/posthog/skills/team/customer-success/impersonation-toolkit:latest
MIT
.claude-plugin/plugin.json
HARDENING.md
LICENSE
README.md
SKILL.md
assets/settings.local.json
scripts/impersonate-audit.sh