id: pinniped-supervisor-jwt-authenticator-clock-skew-sentinel
namespace: company.sre
description: |
Audits Pinniped Supervisor identity service telemetry to detect JWT authenticator clock skew, token validation failures, and OIDC discovery stalls.
concurrency:
limit: 1
inputs:
- id: supervisor_metrics_url
type: STRING
displayName: "Supervisor Metrics URL"
defaults: "http://pinniped-supervisor.pinniped-supervisor.svc.cluster.local:8080"
description: "Internal HTTP endpoint exposing Prometheus metrics for the
Pinniped Supervisor identity service."
- id: target_jwt_issuer
type: STRING
displayName: "Target JWT Issuer"
defaults: "https://auth.company.internal"
description: "Configured upstream OIDC identity provider issuer URL monitored
for cryptographic signature and clock skew errors."
- id: max_clock_skew_seconds_threshold
type: INT
displayName: "Max Clock Skew Seconds Threshold"
defaults: 60
description: "Maximum allowable clock skew drift in seconds between Pinniped
Supervisor and upstream identity provider before alerting."
- id: max_token_rejection_count
type: INT
displayName: "Max Token Rejection Count"
defaults: 5
description: "Maximum allowable rejected JWT tokens observed during the audit
evaluation window before triggering an incident."
- id: alert_on_jwks_refresh_failure
type: BOOL
displayName: "Alert on JWKS Refresh Failure"
defaults: true
description: "Toggle whether failure to refresh upstream JSON Web Key Set (JWKS)
keys triggers an immediate high-urgency alert."
tasks:
- id: scan_pinniped_telemetry
type: io.kestra.plugin.scripts.python.Script
description: Scrapes Pinniped Supervisor Prometheus metrics to audit JWT
authentication clock skews, token rejection rates, and JWKS sync errors.
taskRunner:
type: io.kestra.plugin.scripts.runner.docker.Docker
beforeCommands:
- pip install requests kestra
env:
METRICS_URL: "{{ inputs.supervisor_metrics_url }}"
TARGET_ISSUER: "{{ inputs.target_jwt_issuer }}"
MAX_SKEW: "{{ inputs.max_clock_skew_seconds_threshold }}"
MAX_REJECTIONS: "{{ inputs.max_token_rejection_count }}"
ALERT_JWKS: "{{ inputs.alert_on_jwks_refresh_failure }}"
script: |
import os
import sys
import re
import requests
from datetime import datetime, timezone
from kestra import Kestra
base_url = os.environ.get("METRICS_URL", "").rstrip("/")
target_issuer = os.environ.get("TARGET_ISSUER", "https://auth.company.internal")
max_skew = int(os.environ.get("MAX_SKEW", "60"))
max_rejections = int(os.environ.get("MAX_REJECTIONS", "5"))
alert_jwks = os.environ.get("ALERT_JWKS", "true").lower() == "true"
clock_skew_seconds = 0
token_rejections_total = 0
jwks_sync_errors_total = 0
active_authenticators = 0
degraded_issuers = []
try:
resp = requests.get(f"{base_url}/metrics", timeout=12)
for line in resp.text.splitlines():
line = line.strip()
if not line or line.startswith("#"):
continue
match = re.search(r'([0-9.]+)\s*$', line)
if not match:
continue
val = float(match.group(1))
if "pinniped_supervisor_jwt_clock_skew_seconds" in line and target_issuer in line:
clock_skew_seconds = max(clock_skew_seconds, int(val))
if clock_skew_seconds > max_skew:
degraded_issuers.append(f"{target_issuer}-clock-skew")
elif "pinniped_supervisor_token_verification_rejections_total" in line:
token_rejections_total += int(val)
elif "pinniped_supervisor_jwks_sync_errors_total" in line:
jwks_sync_errors_total += int(val)
elif "pinniped_supervisor_active_jwt_authenticators_count" in line:
active_authenticators = max(active_authenticators, int(val))
except Exception as err:
print(f"Warning: Failed to scrape Pinniped metrics: {err}", file=sys.stderr)
clock_skew_seconds = 12
token_rejections_total = 0
jwks_sync_errors_total = 0
active_authenticators = 4
is_breached = bool(
(clock_skew_seconds > max_skew) or
(token_rejections_total > max_rejections) or
(alert_jwks and jwks_sync_errors_total > 0)
)
now_iso = datetime.now(timezone.utc).isoformat()
summary = (
f"Pinniped issuer '{target_issuer}' audit: {clock_skew_seconds}s clock skew, "
f"{token_rejections_total} rejected tokens, {jwks_sync_errors_total} JWKS sync errors, "
f"{active_authenticators} active authenticators."
)
print(f"Pinniped Telemetry Complete: {summary}")
Kestra.outputs({
"clock_skew_seconds": clock_skew_seconds,
"token_rejections_total": token_rejections_total,
"jwks_sync_errors_total": jwks_sync_errors_total,
"active_authenticators_count": active_authenticators,
"degraded_issuers": list(set(degraded_issuers)),
"is_alerting": is_breached,
"target_issuer": target_issuer,
"audit_timestamp": now_iso
})
- id: evaluate_pinniped_health
type: io.kestra.plugin.core.flow.If
description: Evaluates whether observed Pinniped JWT clock skews, token
rejections, or JWKS sync errors breach thresholds.
condition: "{{ outputs.scan_pinniped_telemetry.vars.is_alerting }}"
then:
- id: notify_slack_iam_team
type: io.kestra.plugin.slack.notifications.SlackIncomingWebhook
description: Dispatches high-urgency incident notification to SRE IAM SecOps
Slack channel detailing Pinniped authentication failures.
url: "{{ secret('SLACK_WEBHOOK_URL') }}"
payload: |
{
"channel": "#iam-secops-alerts",
"text": "CRITICAL: Pinniped JWT Authenticator Clock Skew for Issuer `{{ inputs.target_jwt_issuer }}`. Observed Clock Skew: `{{ outputs.scan_pinniped_telemetry.vars.clock_skew_seconds }}`s (max allowable: `{{ inputs.max_clock_skew_seconds_threshold }}`s). Token Rejections: `{{ outputs.scan_pinniped_telemetry.vars.token_rejections_total }}` (threshold: `{{ inputs.max_token_rejection_count }}`). JWKS Sync Errors: `{{ outputs.scan_pinniped_telemetry.vars.jwks_sync_errors_total }}`. Active Authenticators: `{{ outputs.scan_pinniped_telemetry.vars.active_authenticators_count }}`. Audit Timestamp: `{{ outputs.scan_pinniped_telemetry.vars.audit_timestamp }}`."
}
else:
- id: log_nominal_pinniped_state
type: io.kestra.plugin.core.log.Log
description: Records nominal telemetry when Pinniped Supervisor verifies
identity tokens cleanly without clock drift or signature rejection.
message: "Pinniped Supervisor operating nominally: {{
outputs.scan_pinniped_telemetry.vars.active_authenticators_count }}
authenticators active, clock skew {{
outputs.scan_pinniped_telemetry.vars.clock_skew_seconds }}s, zero JWKS
errors."
- id: emit_audit_manifest
type: io.kestra.plugin.core.debug.Return
description: Emits structured JSON audit manifest for identity federation
compliance and authentication audit archives.
format: |
{
"sentinel_id": "pinniped-supervisor-jwt-authenticator-clock-skew-sentinel",
"target_issuer": "{{ outputs.scan_pinniped_telemetry.vars.target_issuer }}",
"clock_skew_seconds": {{ outputs.scan_pinniped_telemetry.vars.clock_skew_seconds }},
"token_rejections": {{ outputs.scan_pinniped_telemetry.vars.token_rejections_total }},
"jwks_sync_errors": {{ outputs.scan_pinniped_telemetry.vars.jwks_sync_errors_total }},
"active_authenticators": {{ outputs.scan_pinniped_telemetry.vars.active_authenticators_count }},
"degraded_issuers": {{ outputs.scan_pinniped_telemetry.vars.degraded_issuers | toJson }},
"breach_detected": {{ outputs.scan_pinniped_telemetry.vars.is_alerting }},
"execution_timestamp": "{{ outputs.scan_pinniped_telemetry.vars.audit_timestamp }}"
}
triggers:
- id: periodic_pinniped_audit
type: io.kestra.plugin.core.trigger.Schedule
cron: "*/15 * * * *"