New to Kestra?
Use blueprints to kickstart your first workflows.
Evaluate a PostHog feature flag, alert Slack when its state drifts from the expected safe value, and log the result.
A feature flag used as a kill switch or a staged rollout gate is only as safe as its current value, and PostHog has no native alert for "this flag is not what it should be right now". A flag flipped on by mistake, or a rollout that silently regressed, sits there until someone happens to check. This blueprint evaluates one flag for a representative user and compares it against the value you declare safe.
This blueprint was created by Mohit Jeswani.
check_flag (io.kestra.plugin.posthog.EvaluateFeatureFlag) asks PostHog for flag_key's
value for distinct_id. allowFailure: true covers an API or host error without failing
the flow outright.evaluate (io.kestra.plugin.core.output.OutputValues) compares the flag's enabled
value against expected_enabled. A failed evaluation (no output at all) is CRITICAL; a
mismatch is DRIFT; a match is OK.route (io.kestra.plugin.core.flow.If):summary logs the actual value and severity, closing the governance cycle.errors alerts Slack if the flow itself fails, for example an invalid API key.EvaluateFeatureFlag used as a standing compliance check rather than a one-off lookup.PostHog resolves the flag; it does not decide what value is safe, compare it against that
expectation, or notify anyone when they diverge. Kestra keeps expected_enabled as a flow
input instead of institutional memory, turns a flag check into a Slack page naming the actual
value, and keeps a full execution history of every run.
phc_...).distinct_id (a canary account, a synthetic test user, or a real user you
are comfortable the flag evaluation targets) with a known expected flag state.PostHog is open source and self-hostable, unlike most plugins in this engagement: run
docker run -d --name posthog -p 8000:8000 posthog/posthog:latest and point posthog_host at
http://localhost:8000 (or http://posthog:8000 from inside the same Docker network) to
validate this flow's logic end to end without a Cloud account.
POSTHOG_API_KEY: the PostHog project API key used by check_flag. In Kestra OSS, provide
it as the base64-encoded environment variable SECRET_POSTHOG_API_KEY.SLACK_WEBHOOK_URL: used by alert and the errors block. In Kestra OSS, provide it as
the base64-encoded environment variable SECRET_SLACK_WEBHOOK_URL.| Input | Type | Default | Allowed values |
|---|---|---|---|
posthog_host |
STRING | https://us.i.posthog.com |
Valid PostHog ingestion host URL |
distinct_id |
STRING | <canary-user-id> |
Distinct user or canary account ID |
flag_key |
STRING | <your-flag-key> |
PostHog feature flag key |
expected_enabled |
BOOL | false |
true, false |
{{ outputs.check_flag.value }}: raw evaluation value (boolean for boolean flag, variant string for multivariate, null if not returned).{{ outputs.check_flag.enabled }}: boolean indicating whether the flag evaluated as enabled.{{ outputs.check_flag.variant }}: variant name for multivariate flags (null if boolean or missing).{{ outputs.evaluate.values.actual_enabled }}: evaluated enabled status or unknown on probe failure.{{ outputs.evaluate.values.severity }}: compliance classification (OK, DRIFT, or CRITICAL).$feature_flag_called event to PostHog on every run, as the
PostHog SDK does by default; a very frequent schedule adds that much event volume to the
project.enabled: false, indistinguishable from a
flag that genuinely evaluates to false. If expected_enabled is also false, a flag that
stopped resolving entirely would read as compliant rather than broken; keep distinct_id
pointed at an account you know the flag actually targets.distinct_id must be an ID PostHog's flag targeting rules actually evaluate against; a
made-up ID with no history may fall back to the flag's default rather than exercising a
specific rollout cohort.POSTHOG_API_KEY and SLACK_WEBHOOK_URL secrets.distinct_id and flag_key to a real flag and a user you know its current value for.expected_enabled to match that known value and run the flow, confirming compliant.expected_enabled to the opposite value and re-run to confirm alert fires with
DRIFT.hourly trigger once expected_enabled reflects the flag's real safe state.flag_key/expected_enabled pairs with io.kestra.plugin.core.flow.Loop
to watch every safety-critical flag in one scheduled run.distinct_id values representing different rollout
cohorts, to catch a cohort-specific regression rather than only a single canary account.io.kestra.plugin.posthog.Capture after a DRIFT result to record a synthetic
flag_drift_detected event back into PostHog's own analytics for trend tracking.