Back to skill

Security audit

cicd-aiops

Security checks for vulnerabilities and agentic risk

Overview

This CI/CD operations skill is transparent about its purpose, but it can perform destructive GitLab/Gitea actions with user tokens and no built-in read-only or approval gate.

Install only if you intend to let an agent operate a self-managed GitLab or Gitea CI/CD environment. Start with a least-privilege or read-only token, avoid putting the master password in plaintext client configs, and require human review outside the tool before enabling destructive writes such as artifact deletion, pipeline cancellation, runner changes, or branch-protection updates.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
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 (20)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
- Bash
metadata: {"openclaw":{"requires":{"anyBins":["cicd-aiops","uvx"]},"optional":{"env":["CICD_AIOPS_CONFIG","CICD_AIOPS_MASTER_PASSWORD"]},"homepage":"https://github.com/AIops-tools/CICD-AIops","emoji":"🔁","os":["macos","linux"]}}
compatibility: >
  Standalone, self-governed CI/CD operations across self-managed GitLab (REST API v4 /api/v4/..., access token via PRIVATE-TOKEN header) and self-hosted Gitea (API v1 /api/v1/..., access token via "Authorization: token"). 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; surfaces one platform lacks (e.g. runner administration on Gitea) raise a teaching error listing what is available. 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 ~/.cicd-aiops/ (relocatable via CICD_AIOPS_HOME).
  Credentials: the GitLab personal/project access token or Gitea access token is stored ENCRYPTED in ~/.cicd-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'cicd-aiops init' to onboard (it asks for the platform and base URL), or 'cicd-aiops secret set <target>' to add one. The store is unlocked by a master password from CICD_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var CICD_<TARGET_NAME_UPPER>_SECRET is still honoured as a fallback with a deprecation warning (migrate with 'cicd-aiops secret migrate'). The token is presented as a PRIVATE-TOKEN header (GitLab) or an Authorization token header (Gitea) at request time and held only in memory; secrets are never logged or echoed.
  State-changing operations pass through the @governed_tool decorator (pre-check + budget guard + audit + risk-tier label). delete_artifacts is risk=high with dry_run + double conf
...[truncated 25 chars]

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
- Bash
metadata: {"openclaw":{"requires":{"anyBins":["cicd-aiops","uvx"]},"optional":{"env":["CICD_AIOPS_CONFIG","CICD_AIOPS_MASTER_PASSWORD"]},"homepage":"https://github.com/AIops-tools/CICD-AIops","emoji":"🔁","os":["macos","linux"]}}
compatibility: >
  Standalone, self-governed CI/CD operations across self-managed GitLab (REST API v4 /api/v4/..., access token via PRIVATE-TOKEN header) and self-hosted Gitea (API v1 /api/v1/..., access token via "Authorization: token"). 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; surfaces one platform lacks (e.g. runner administration on Gitea) raise a teaching error listing what is available. 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 ~/.cicd-aiops/ (relocatable via CICD_AIOPS_HOME).
  Credentials: the GitLab personal/project access token or Gitea access token is stored ENCRYPTED in ~/.cicd-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'cicd-aiops init' to onboard (it asks for the platform and base URL), or 'cicd-aiops secret set <target>' to add one. The store is unlocked by a master password from CICD_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var CICD_<TARGET_NAME_UPPER>_SECRET is still honoured as a fallback with a deprecation warning (migrate with 'cicd-aiops secret migrate'). The token is presented as a PRIVATE-TOKEN header (GitLab) or an Authorization token header (Gitea) at request time and held only in memory; secrets are never logged or echoed.
  State-changing operations pass through the @governed_tool decorator (pre-check + budget guard + audit + risk-tier label). delete_artifacts is risk=high with dry_run + double conf
...[truncated 25 chars]

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
- Bash
metadata: {"openclaw":{"requires":{"anyBins":["cicd-aiops","uvx"]},"optional":{"env":["CICD_AIOPS_CONFIG","CICD_AIOPS_MASTER_PASSWORD"]},"homepage":"https://github.com/AIops-tools/CICD-AIops","emoji":"🔁","os":["macos","linux"]}}
compatibility: >
  Standalone, self-governed CI/CD operations across self-managed GitLab (REST API v4 /api/v4/..., access token via PRIVATE-TOKEN header) and self-hosted Gitea (API v1 /api/v1/..., access token via "Authorization: token"). 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; surfaces one platform lacks (e.g. runner administration on Gitea) raise a teaching error listing what is available. 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 ~/.cicd-aiops/ (relocatable via CICD_AIOPS_HOME).
  Credentials: the GitLab personal/project access token or Gitea access token is stored ENCRYPTED in ~/.cicd-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'cicd-aiops init' to onboard (it asks for the platform and base URL), or 'cicd-aiops secret set <target>' to add one. The store is unlocked by a master password from CICD_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var CICD_<TARGET_NAME_UPPER>_SECRET is still honoured as a fallback with a deprecation warning (migrate with 'cicd-aiops secret migrate'). The token is presented as a PRIVATE-TOKEN header (GitLab) or an Authorization token header (Gitea) at request time and held only in memory; secrets are never logged or echoed.
  State-changing operations pass through the @governed_tool decorator (pre-check + budget guard + audit + risk-tier label). delete_artifacts is risk=high with dry_run + double conf
...[truncated 25 chars]

Credential Access

High
Category
Privilege Escalation
Confidence
84% confidence
Finding

The skill explicitly states there is no read-only switch, policy file, or approval gate, and that write permission is effectively determined by whatever token the agent is given. In a tool capable of retrying/canceling pipelines, pausing runners, changing branch protection, and deleting artifacts, absence of an internal authorization barrier materially increases the risk of accidental or unauthorized destructive actions if the agent is over-privileged.

Content

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

md
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 token you connect it with (a GitLab/Gitea access token without write
scope — writes then fail at the server). There is no read-only switch, policy
file, or approval gate.

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 12)May include surrounding context.

bash
cicd-aiops init                 # onboarding wizard (platform, base URL, encrypted token)
cicd-aiops doctor               # config + secrets + connectivity + token-scope probe
cicd-aiops doctor --skip-auth   # config/secrets checks only
cicd-aiops overview             # version, identity, projects, runners
cicd-aiops projects [--search x] [--limit N]

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 60)May include surrounding context.

cicd-aiops secret set # store a token (encrypted) cicd-aiops secret list # names only, never values cicd-aiops secret remove cicd-aiops secret migrate # legacy .env → encrypted store

text

## MCP

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
## 2. Create a token on the server

**GitLab (self-managed)** — Preferences → Access Tokens → new personal (or
project) access token with the `api` scope. Runner administration
(`pause_runner`/`resume_runner`, `/runners/all`) additionally needs an
admin-capable account.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
## 2. Create a token on the server

**GitLab (self-managed)** — Preferences → Access Tokens → new personal (or
project) access token with the `api` scope. Runner administration
(`pause_runner`/`resume_runner`, `/runners/all`) additionally needs an
admin-capable account.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
## 2. Create a token on the server

**GitLab (self-managed)** — Preferences → Access Tokens → new personal (or
project) access token with the `api` scope. Runner administration
(`pause_runner`/`resume_runner`, `/runners/all`) additionally needs an
admin-capable account.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
## 2. Create a token on the server

**GitLab (self-managed)** — Preferences → Access Tokens → new personal (or
project) access token with the `api` scope. Runner administration
(`pause_runner`/`resume_runner`, `/runners/all`) additionally needs an
admin-capable account.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
automatically).
3. **TLS verification** — defaults to **Yes**; answer No only for
   self-signed lab certs.
4. **Access token** — prompted hidden, stored encrypted, never in
   config.yaml.

Resulting `~/.cicd-aiops/config.yaml`:

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest advertises a built-in governance harness with policy enforcement, but later text explicitly says there is no policy file, approval gate, or authorization control. That mismatch can cause operators or upstream agents to overtrust the skill's safety properties and allow destructive CI/CD actions under the false assumption that independent policy enforcement exists.

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 · SKILL.md (reported line 23)May include surrounding context.

md
metadata: {"openclaw":{"requires":{"anyBins":["cicd-aiops","uvx"]},"optional":{"env":["CICD_AIOPS_CONFIG","CICD_AIOPS_MASTER_PASSWORD"]},"homepage":"https://github.com/AIops-tools/CICD-AIops","emoji":"🔁","os":["macos","linux"]}}
compatibility: >
  Standalone, self-governed CI/CD operations across self-managed GitLab (REST API v4 /api/v4/..., access token via PRIVATE-TOKEN header) and self-hosted Gitea (API v1 /api/v1/..., access token via "Authorization: token"). 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; surfaces one platform lacks (e.g. runner administration on Gitea) raise a teaching error listing what is available. 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 ~/.cicd-aiops/ (relocatable via CICD_AIOPS_HOME).
  Credentials: the GitLab personal/project access token or Gitea access token is stored ENCRYPTED in ~/.cicd-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'cicd-aiops init' to onboard (it asks for the platform and base URL), or 'cicd-aiops secret set <target>' to add one. The store is unlocked by a master password from CICD_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var CICD_<TARGET_NAME_UPPER>_SECRET is still honoured as a fallback with a deprecation warning (migrate with 'cicd-aiops secret migrate'). The token is presented as a PRIVATE-TOKEN header (GitLab) or an Authorization token header (Gitea) at request time and held only in memory; secrets are never logged or echoed.
  State-changing operations pass through the @governed_tool decorator (pre-check + budget guard + audit + risk-tier label). delete_artifacts is risk=high with dry_run + double confirmatio
...[truncated 25 chars]

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Saying all state-changing operations pass through a governed decorator suggests meaningful access control, but later documentation clarifies writes are not permission-gated beyond the server token's native scope. This can mislead an agent into treating destructive operations as independently safeguarded when they are only audited after the fact.

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 · SKILL.md (reported line 122)May include surrounding context.

md
## Common Workflows

Each recipe starts from one of the four RCAs and ends in a governed write.
Every CLI write accepts `--dry-run` and otherwise double-confirms. Note that
runner administration and pipeline retry/cancel are **GitLab-only** — on a
Gitea target those tools raise a teaching error listing what is available.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
95% confidence
Finding

The guardrails explicitly state that the tool does not enforce read-only mode or approvals, and that write control is delegated to token scope or the outer agent prompt. In an agentic setting, prompt-only restrictions are not a reliable authorization boundary, so a mis-scoped token or prompt bypass can let the model perform destructive CI/CD actions without an in-tool approval check.

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 token you connect with.** Give it a GitLab/Gitea access token without

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 12)May include surrounding context.

bash
cicd-aiops init                 # onboarding wizard (platform, base URL, encrypted token)
cicd-aiops doctor               # config + secrets + connectivity + token-scope probe
cicd-aiops doctor --skip-auth   # config/secrets checks only
cicd-aiops overview             # version, identity, projects, runners
cicd-aiops projects [--search x] [--limit N]

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/setup-guide.md (reported line 11)May include surrounding context.

md
Requires Python >= 3.11.

## 2. Create a token on the server

**GitLab (self-managed)** — Preferences → Access Tokens → new personal (or
project) access token with the `api` scope. Runner administration

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The guide tells users to place the master password directly in MCP client configuration via an env block, but does not warn that this may store the secret in plaintext in local config files, backups, logs, or UI-visible settings. Because this password protects the encrypted token store, exposure can lead to decryption of CI/CD access tokens and subsequent compromise of the GitLab/Gitea instance.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The documentation creates a misleading security claim: the skill metadata advertises a built-in governance harness for writes, but the setup guide states the skill does not decide whether a write is permitted and that authorization depends on agent judgment or token scope. This can cause operators to overtrust the tool's safety controls and perform destructive CI/CD actions under the false assumption that policy gates are enforced.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.