Back to skill

Security audit

identity-aiops

Security checks for vulnerabilities and agentic risk

Overview

This is coherent identity-operations tooling, but it needs Review because MCP writes can make high-impact Keycloak/authentik changes without an enforced approval or read-only control.

Install only with a least-privileged read-only Keycloak service account or authentik token at first. Do not grant manage-users or manage-clients unless you are comfortable with the agent being able to disable users, revoke sessions, change redirect URI boundaries, or rotate client secrets through MCP without a separate tool-side approval gate. Treat IDENTITY_AIOPS_MASTER_PASSWORD and any legacy environment secrets as highly sensitive.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:220
Finding

MCP Write Operations Lack an Enforced Authorization or Confirmation Gate

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:220-235
Related Evidence: references/agent-guardrails.md:11-22, references/cli-reference.md:3-5
Vulnerability Type: Missing authorization gate for state-changing identity operations
Risk Level: High

Vulnerable documentation and effective behavior:

text
The skill delivers reads and writes and records them; it does **not** decide
whether a write is permitted. That is your agent's judgement, or the permission
of the account you connect it with (a Keycloak service account or authentik
token without `manage-*` scope — writes then fail at the server). There is no
read-only switch, policy file, or approval gate.

- **Audit is the guarantee, and it is not bypassable.** Every call — MCP and
  CLI alike — lands an audit row in `~/.identity-aiops/audit.db` (relocatable
  via `IDENTITY_AIOPS_HOME`): params, status, and the risk tier.
- `IDENTITY_AUDIT_APPROVED_BY` / `IDENTITY_AUDIT_RATIONALE` are optional
  annotations recorded on the row (who/why); they are never required and never
  block.
- **Risk tier** — a descriptive label on the audit row derived from
  `risk_level` (`enable_user`, `update_client_redirect_uris`,
  `rotate_client_secret` = high; `disable_user`, `revoke_user_sessions`,
  `require_password_reset` = medium); it gates nothing. Writes support
  `--dry-run` and double confirmation at the CLI.

Technical Analysis

The Skill exposes state-changing MCP operations while explicitly delegating authorization to the agent's judgment or the permissions of the connected IdP account. It provides no enforced read-only mode, policy gate, mandatory approval token, or confirmation requirement for direct MCP calls.

The CLI's --dry-run and double-confirmation controls do not protect the direct MCP execution path. Optional audit fields and risk labels only record context; the documentation expressly states that they never block exec ...[truncated 2173 chars]

Remediation
View remediation

Remediation Suggestions

  • Make all direct MCP writes dry-run by default.
  • Require a short-lived, operation-bound approval token before execution. Bind it to the exact tool, target identity or client, proposed parameters, and expiration time.
  • Display the complete proposed change and require explicit operator approval before issuing the token.
  • Add an enforced read-only mode that removes or rejects all write tools regardless of model instructions.
  • Require stronger confirmation for irreversible actions such as session revocation and client-secret rotation.
  • Convert IDENTITY_AUDIT_APPROVED_BY and IDENTITY_AUDIT_RATIONALE from optional annotations into validated approval evidence where policy requires it.
  • Retain audit logging and risk labels, but treat them as defense-in-depth rather than authorization controls.
  • Configure the IdP account with the minimum necessary roles so an authorization failure cannot affect resources outside the intended operational scope.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (10)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
70% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/cli-reference.md (reported line 14)May include surrounding context.

bash
identity-aiops init                 # onboarding wizard (platform, base URL, realm, secret)
identity-aiops doctor               # config + secrets + token acquisition + user-count probe
identity-aiops doctor --skip-auth   # config/secrets checks only (no network)
identity-aiops overview             # one-shot estate summary
identity-aiops mcp                  # start the MCP server (stdio)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/cli-reference.md (reported line 25)May include surrounding context.

identity-aiops secret set # store/replace a secret (hidden prompt) identity-aiops secret list # target names only — never values identity-aiops secret remove identity-aiops secret migrate # legacy .env / env vars → secrets.enc

text

Master password: `IDENTITY_AIOPS_MASTER_PASSWORD` (non-interactive/MCP) or an

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 23)May include surrounding context.

md
metadata: {"openclaw":{"requires":{"anyBins":["identity-aiops","uvx"]},"optional":{"env":["IDENTITY_AIOPS_CONFIG","IDENTITY_AIOPS_MASTER_PASSWORD"]},"homepage":"https://github.com/AIops-tools/Identity-AIops","emoji":"🔐","os":["macos","linux"]}}
compatibility: >
  Standalone, self-governed identity-provider operations across Keycloak (admin REST API /admin/realms/{realm}/..., OAuth2 client-credentials grant against the realm token endpoint with automatic refresh-on-401) and authentik (API v3 /api/v3/..., long-lived API token as a Bearer header). Each target in the config names its own platform, and a name-keyed platform registry selects the API shape, so the same tools work on both and one config can span a mixed estate. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no external skill-family dependency.
  All write operations are audited to a local SQLite DB under ~/.identity-aiops/ (relocatable via IDENTITY_AIOPS_HOME).
  Credentials: the Keycloak confidential client's client secret or the authentik API token is stored ENCRYPTED in ~/.identity-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'identity-aiops init' to onboard (it asks for the platform, base URL, and — Keycloak — realm + client_id), or 'identity-aiops secret set <target>' to add one. The store is unlocked by a master password from IDENTITY_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var IDENTITY_<TARGET_NAME_UPPER>_SECRET is still honoured as a fallback with a deprecation warning (migrate with 'identity-aiops secret migrate'). Secrets are held only in memory, never logged or echoed; rotate_client_secret returns and records masked fingerprints only.
  State-changing operations pass through the @governed_tool decorator (budget guard + audit + risk-tier labelling). enable_user, update_client_redirect_uris, and rotate_client_secret are risk=hi
...[truncated 25 chars]

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 122)May include surrounding context.

md
Each recipe starts from a read or one of the four RCAs and ends in a governed
write. The **RCAs are MCP tools** (`login_failure_rca`, `stale_access_audit`,
`client_misconfig_audit`, `mfa_coverage_analysis`) — call them through the MCP
server; the CLI covers the reads and the writes. Every CLI write accepts
`--dry-run` and otherwise double-confirms.

### 1. "We're being brute-forced — contain it"

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
94% confidence
Finding

The guardrail explicitly states that the tool does not enforce read-only mode or approval for writes, relying instead on external account permissions and prompt discipline. In an agentic setting, this creates a real autonomous-action risk: if the connected credentials have write privileges, a model can disable users, revoke sessions, or modify client settings without an in-tool authorization checkpoint.

Content

Scanner excerpt · references/agent-guardrails.md (reported line 15)May include surrounding context.

md
## Authorization is not this tool's job — decide it where it belongs

Whether a write should happen is your decision, or the account's. The tool does
not gate it — there is no read-only switch and no approval prompt to configure.
The two right places to control read vs write:

- **The account you connect with.** Give the Keycloak service account (or the

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This capability document advertises governed write operations that can disable accounts, enable accounts, revoke sessions, force password resets, replace redirect URIs, and rotate client secrets, but it does not prominently warn about operational impact, lockout risk, credential invalidation, or application outage potential. In an agent skill, that omission is security-relevant because the model may treat these actions as routine and execute them without clearly communicating consequences or requiring stronger confirmation for high-risk identity changes.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/cli-reference.md (reported line 3)May include surrounding context.

md
# identity-aiops CLI reference

All read commands print normalized JSON. All write commands take `--dry-run`
(preview, no call, no audit) and otherwise require **double confirmation**;
confirmed writes execute through the governed MCP twins, so they land in
`~/.identity-aiops/audit.db` with undo where applicable. `--target/-t` selects

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · references/cli-reference.md (reported line 14)May include surrounding context.

bash
identity-aiops init                 # onboarding wizard (platform, base URL, realm, secret)
identity-aiops doctor               # config + secrets + token acquisition + user-count probe
identity-aiops doctor --skip-auth   # config/secrets checks only (no network)
identity-aiops overview             # one-shot estate summary
identity-aiops mcp                  # start the MCP server (stdio)

Session Persistence

Medium
Category
Rogue Agent
Confidence
84% confidence
Finding

The guide instructs users to create a long-lived confidential client or API token for administrative access to the identity provider, which creates persistent machine credentials with broad realm-management capabilities. If these credentials are stolen from the host, config, MCP environment, or logs, an attacker could gain durable read access and potentially user/client management powers over the IdP.

Content

Scanner excerpt · references/setup-guide.md (reported line 17)May include surrounding context.

md
## 2. What you need per IdP

- **Keycloak** — a **confidential client** with *Client authentication* ON and
  *Service accounts roles* enabled (Clients → Create client). Grant its service
  account the `realm-management` roles the agent should have:
  - reads/analyses only: `view-users`, `view-events`, `view-clients`,
    `view-realm`, `view-identity-providers`

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/setup-guide.md (reported line 92)May include surrounding context.

md
## 6. Security notes

- Secrets: Fernet-encrypted (scrypt-derived key), chmod 600, never plaintext;
  legacy `IDENTITY_<TARGET>_SECRET` env fallback warns and should be migrated
  (`identity-aiops secret migrate`).
- Least privilege: scope the Keycloak service account / authentik token to the

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/cli-reference.md:28