{
  "schema": "aaes/capability-pack/1",
  "provider": "sonarqube",
  "version": "1.0.0",
  "description": "SonarQube Server: read projects, issues, code metrics and quality gate results; change issue status or a project’s quality gate; and create or delete projects.",
  "notes": "The endpoint host 'sonarqube-server.invalid' is a reserved non-production placeholder (an RFC 2606 reserved TLD): substitute the customer's own SonarQube Server base URL before enabling, in every endpoint, in the resource locator and in every egress allowlist entry. The allowlist matches exactly, so endpoints and allowlist must be substituted together, and substitution is a required deployment step. Request parameters: the registered paths are operation paths only — project, issue and gate selection are sent as caller-supplied form parameters (project, issue, gateName per each operation's parameter names), and nothing in this registration binds or records them at installation: they remain caller-controlled on every request unless a separately reviewed control restricts them. POST operations use application/x-www-form-urlencoded bodies per SonarQube's Web API guidance (parameters in the body, not the URI query string, so they are passed securely).\n\nApproval classification: collection reads (projects, issues) and single-resource reads (measures, quality gate status) sit at the minimum R0 tier; issue transitions and quality gate assignment are reversible workflow/configuration updates at the minimum R2 tier — but transitioning a security issue to accepted or false-positive, or changing a project's quality gate, changes what the quality gate reports and can hide a real finding from release controls: the minimum R2 tier is a minimum, and policy should scope these capabilities to named actors and projects.\n\nProject delete sits at the minimum R3 tier: deleting a project removes it and its analysis history, and delete is one of the designated actions requiring human approval.\n\nDocumented exclusions: this pack does not register user and group administration (api/users, api/user_groups), permission management (api/permissions — granting permissions is access-granting and needs its own review), token administration endpoints (api/user_tokens — token issuance and revocation are an external custody process, see the credential note), quality gate and quality profile creation/modification beyond project assignment (instance-wide governance settings), webhook management, analysis submission (the scanner's ce endpoints), and the X-Sonar-Passcode system authentication scheme (a server-wide passcode for monitoring endpoints, not a per-user credential — not registered).\n\nSource basis: SonarQube documents its web services in the running server's own /web_api console, which is client-rendered; the HTML console returned only the client shell, but the console's machine-readable listing on SonarSource's public instance (https://next.sonarqube.com/sonarqube/api/webservices/list) was retrieved during the documented review and documents every registered operation — api/projects/search (GET), api/issues/search (GET, Browse on the project), api/measures/component (GET, Browse or Execute Analysis on the project), api/qualitygates/project_status (GET), api/issues/do_transition (POST; transitions confirm/unconfirm/reopen/resolve/falsepositive/wontfix/accept, with accept, wontfix and falsepositive requiring Administer Issues), api/qualitygates/select (POST; Administer Quality Gates or Administer on the project; params gateName and projectKey), api/projects/create (POST; global Create Projects) and api/projects/delete (POST; Administer System or Administer on the project).\n\nInstance versions differ, so each path and parameter set must still be confirmed against the target instance's own /web_api console before enabling.",
  "credential": {
    "secret_ref_id": "secret-ref-sonarqube-user-token",
    "custody": "customer_vault",
    "inject": "header",
    "inject_name": "Authorization",
    "note": "A SonarQube Server user token, held in the client's own secret manager. Token issuance is external: a user (or, for service accounts, an administrator via the instance's token administration) generates the token under Account > My Account > Security, and the deployment's custody job stores it under this reference. The stored material must be the complete Authorization header value (scheme included): 'Bearer ' followed by the token — SonarQube's Web API documentation recommends the bearer scheme and documents that tokens may alternatively be sent as the username half of HTTP Basic with an empty password; this pack registers the Bearer form only.\n\nToken permissions: a USER token carries ALL the permissions of the issuing user (SonarQube states a global admin's user token gives full rights to the instance), so the token must be issued for a dedicated least-privilege service account holding only the permissions the enabled capabilities need (Browse on the bound projects for the reads; Administer Issues on the bound projects for issue transitions; the instance's quality-gate administration permission for gate assignment; the global Create Projects permission for project creation; Administer on a project only where project deletion is enabled — permission names and the supported transition set were verified during the documented review against the machine-readable web services listing on SonarSource's public instance (next.sonarqube.com/api/webservices/list), but instance versions differ, so confirm against the target instance's own /web_api console at deployment) — never a personal admin's token.\n\nProject and global ANALYSIS tokens exist but are scoped to analysis and do not fit these capabilities.\n\nExpiry and revocation: tokens may be created with an expiration or with no expiration; Enterprise editions let an administrator enforce a maximum lifetime; tokens can be revoked at any time under My Account > Security, and a project analysis token stops working if its author loses Execute Analysis permission. SonarQube adds a SonarQube-Authentication-Token-Expiration header to API responses so a custody job can track upcoming expiry; an expired or revoked value fails closed.\n\nRevocation limit: revoking the service account's SESSION or changing its password does not invalidate already-issued tokens — revocation is per-token.\n\nExecutor hygiene: the value must live only in executor memory for the lifetime of a call, must never be written to logs, traces or diagnostics, and must not appear in crash dumps; a deployment that cannot meet that bar must not enable the pack."
  },
  "capabilities": [
    {
      "capability_id": "sonarqube.projects.search",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "sonarqube-server.invalid"
      ],
      "endpoint": "https://sonarqube-server.invalid/api/projects/search",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-sonarqube-user-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "sonarqube-instance",
      "description": "Search and list projects on the instance — a collection read of project keys, names and visibility classified as internal data.\n\nThe host is a reserved placeholder: substitute the customer's SonarQube Server base URL before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "sonarqube.issues.search",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "pii",
      "egress_allowlist": [
        "sonarqube-server.invalid"
      ],
      "endpoint": "https://sonarqube-server.invalid/api/issues/search",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-sonarqube-user-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "sonarqube-instance",
      "description": "Search issues (bugs, vulnerabilities, code smells) across projects — a collection read. Results can include assignee logins, source file paths and rule details: the developer identifiers in results are personal data, so the capability is classified as pii (personal data).\n\nThe host is a reserved placeholder: substitute before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "sonarqube.measures.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "sonarqube-server.invalid"
      ],
      "endpoint": "https://sonarqube-server.invalid/api/measures/component",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-sonarqube-user-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "sonarqube-instance",
      "description": "Read measures (code metrics such as ncloc, code_smells, complexity, coverage) for one component — the operation SonarQube's own Web API guide uses as its worked example. Reading a private project's measures requires the token's user to hold Browse permission on that project, which is the least-privilege boundary.\n\nThe host is a reserved placeholder: substitute before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "sonarqube.qualitygates.status.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "sonarqube-server.invalid"
      ],
      "endpoint": "https://sonarqube-server.invalid/api/qualitygates/project_status",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-sonarqube-user-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "sonarqube-instance",
      "description": "Read a project's quality gate status (pass/fail and the conditions evaluated). This is a read only — it does not register changing the gate result or bypassing the gate.\n\nThe host is a reserved placeholder: substitute before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "sonarqube.issue.transition",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R2",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "sonarqube-server.invalid"
      ],
      "endpoint": "https://sonarqube-server.invalid/api/issues/do_transition",
      "method": "POST",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-sonarqube-user-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "update"
      ],
      "resource_id": "sonarqube-instance",
      "description": "Change an issue's workflow status: confirm, unconfirm, reopen, resolve as fixed, mark false-positive, or accept. A later transition can restore its status, so the action is registered as update at R2.\n\nAccepting a security issue or marking it false-positive can remove it from default gate evaluation. Limit policy to named actors and require review.\n\nThe caller supplies the issue key and transition as form parameters; the registration binds neither. The documented review verified confirm, unconfirm, reopen, resolve, falsepositive, wontfix, accept, and the hotspot transitions resolveasreviewed/resetastoreview against the public web services listing. Confirm the supported set in the target instance's /web_api console because versions differ.",
      "requires_review": true
    },
    {
      "capability_id": "sonarqube.qualitygate.assign",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R2",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "sonarqube-server.invalid"
      ],
      "endpoint": "https://sonarqube-server.invalid/api/qualitygates/select",
      "method": "POST",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-sonarqube-user-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "update"
      ],
      "resource_id": "sonarqube-instance",
      "description": "Assign a named quality gate to a project. Reassigning another gate or the default reverses the configuration, so the action is registered as update at R2. A weaker gate weakens release controls; restrict it through policy.\n\nThis registers the project-to-gate association only. Gate creation, modification, set_as_default, and condition management are excluded. The caller supplies the project key and gate name as form parameters; the registration binds neither.",
      "requires_review": true
    },
    {
      "capability_id": "sonarqube.project.create",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R2",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "sonarqube-server.invalid"
      ],
      "endpoint": "https://sonarqube-server.invalid/api/projects/create",
      "method": "POST",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-sonarqube-user-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "create"
      ],
      "resource_id": "sonarqube-instance",
      "description": "Create a project (name, key and optional visibility as form parameters). Registered as create at the minimum R2 tier; a created project can be removed by the registered delete capability. Creating a project does not analyze code — analysis submission through the scanner and compute-engine endpoints is not registered by this pack.\n\nThe host is a reserved placeholder: substitute before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "sonarqube.project.delete",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R3",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "sonarqube-server.invalid"
      ],
      "endpoint": "https://sonarqube-server.invalid/api/projects/delete",
      "method": "POST",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-sonarqube-user-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "delete"
      ],
      "resource_id": "sonarqube-instance",
      "description": "Delete a project, removing it and its analysis history, issues and measures from the instance. This pack registers no undelete or restoration operation for a deleted project, and the Web API reference available to this review documents none; delete is one of the designated actions requiring human approval.\n\nOn supported AAES-mediated execution paths, irreversible actions require approval by an authorized person; this does not prevent calls through bypass or observation-only paths. This sits at the minimum R3 tier. Bulk project deletion (api/projects/bulk_delete) is deliberately not registered. The project key is a caller-supplied form parameter — this registration does not bind it.",
      "requires_review": true
    }
  ],
  "resources": [
    {
      "resource_id": "sonarqube-instance",
      "kind": "api",
      "locator": "https://sonarqube-server.invalid/api",
      "data_class": "pii",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    }
  ],
  "review": {
    "state": "library",
    "date": "2026-09-22",
    "sources": [
      "https://docs.sonarsource.com/sonarqube-server/user-guide/managing-tokens.md (retrieved 2026-09-21)",
      "https://docs.sonarsource.com/sonarqube-server/extension-guide/web-api.md (retrieved 2026-09-21)",
      "https://next.sonarqube.com/sonarqube/api/webservices/list (retrieved 2026-09-21)"
    ],
    "reviewer_id": "aaes-eng"
  }
}
