{
  "schema": "aaes/capability-pack/1",
  "provider": "confluent",
  "version": "1.0.0",
  "description": "Confluent Cloud management APIs: read environments, Kafka clusters and topics, create and update clusters, delete clusters and topics, and revoke API keys.",
  "notes": "Two endpoint hosts appear in this pack, and both are reserved non-production placeholders (RFC 2606 reserved TLD): 'confluent-cloud.invalid' stands in for the Confluent Cloud management API host (the documented host is api.confluent.cloud, serving the org/v2, cmk/v2 and iam/v2 API groups), and 'confluent-cluster.invalid' stands in for a Kafka cluster's own per-cluster Kafka REST endpoint host (documented shape: a pkc-... host specific to each cluster), which serves the kafka/v3 topic operations.\n\nSubstitute both before enabling — in every endpoint, in both resource locators and in every egress allowlist entry; the allowlist matches exactly, and substitution is a required deployment step. ENV_ID, CLUSTER_ID, TOPIC_NAME and KEY_ID are placeholders the deployment binds to concrete resources before enabling. Key scopes: management API calls take a Cloud API key scoped for cloud resource management, while the topic operations on a cluster's own endpoint take a resource-specific API key scoped to that Kafka cluster — the deployment must store the key whose scope matches the capability (per-capability secret_ref overrides exist for exactly this), or operate two references; one key does not honestly cover both surfaces.\n\nExcluded operations: API key CREATION (POST /iam/v2/api-keys — minting new credentials stays with the Console or CLI under direct human control; this pack registers only revocation), user and service-account management and invitations, RBAC role bindings and ACL management (granting access to principals is access-sharing and deserves its own review), connector management (connectors move data between systems — send/share semantics needing their own review), Schema Registry writes (subject deletion and compatibility changes), ksqlDB and Flink statement execution, produce/consume data-plane operations (Kafka REST produce is message sending), cluster networking (PrivateLink, peering, transit gateway) and Marketplace/billing operations.\n\nThe Confluent API reference's per-endpoint pages are client-side rendered; the routes registered here follow the documented API-group shapes (org/v2, cmk/v2, iam/v2, kafka/v3) and were verified on 2026-09-21 against the retrieved Confluent OpenAPI specification (see the review record), not only the overview and authentication pages. Verified cluster contract: GET and DELETE require the environment query parameter. PATCH takes no query parameters and requires spec.environment in the request body, as established by the retrieved OpenAPI specification; see the update capability.",
  "credential": {
    "secret_ref_id": "secret-ref-confluent-cloud-api-key",
    "custody": "customer_vault",
    "inject": "header",
    "inject_name": "Authorization",
    "note": "A Confluent Cloud API key held in the client's own secret manager. Authentication is HTTP Basic over the key pair: the stored material must be the complete Authorization header value — the scheme 'Basic', one separating space, then the Base64 encoding of 'API_KEY_ID:API_SECRET' — and the injector injects the stored value verbatim. Keys are issued in the Confluent Cloud Console or CLI, and each key is owned by a principal (user account or service account) whose permissions the key inherits; permissions live on the principal, not on the key.\n\nKey permissions: a Cloud API key scoped for cloud resource management covers the org/v2, cmk/v2 and iam/v2 management endpoints, while the kafka/v3 topic operations on a cluster's own endpoint require a resource-specific API key scoped to that Kafka cluster — store the key matching each capability's surface (per-capability secret_ref_id overrides exist for this), and do not pretend one reference covers both. This pack names that second reference 'secret-ref-confluent-kafka-api-key': its stored material has the identical wire format — 'Basic', one space, then Base64 of 'API_KEY_ID:API_SECRET' — but the underlying key is a resource-specific API key created for one Kafka cluster (the fetched api-keys page documents that Kafka-cluster-scoped keys specify the Environment and the cluster at creation), and its lifecycle matches the Cloud key's: no documented expiry, valid until deleted in the Console/CLI or until its owning principal is deleted, rotation by issue-replace-delete.\n\nLeast privilege: Confluent strongly recommends service accounts over user accounts for production; use a dedicated service account per integration with only the roles or ACLs these capabilities need, and note that key permissions track the principal's roles as they change.\n\nExpiry and revocation: the reviewed documentation describes no key expiry — a key remains valid until it is deleted in the Console/CLI or until its owning principal is deleted (which automatically deletes all its keys); disabling the ability to create new keys does not invalidate already-issued keys, so revocation means deleting each issued key, and rotation means issuing a replacement, updating this reference, then deleting the old key.\n\nRotation ownership sits with an external deployment process; the executor performs no key lifecycle itself.\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": "confluent.environments.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "confluent-cloud.invalid"
      ],
      "endpoint": "https://confluent-cloud.invalid/org/v2/environments",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-confluent-cloud-api-key",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "confluent-environment",
      "description": "List the environments in the Confluent Cloud organization: names and ids, which reveal org structure.\n\nThe registered path covers the collection read only — single-environment reads are not registered.\n\nThe host is a reserved placeholder: substitute the real Confluent Cloud management API host before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "confluent.kafka_clusters.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "confluent-cloud.invalid"
      ],
      "endpoint": "https://confluent-cloud.invalid/cmk/v2/clusters?environment=ENV_ID",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-confluent-cloud-api-key",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "confluent-environment",
      "description": "List the Kafka clusters in one environment: names, types, cloud providers, regions and provisioning status.\n\nThe registered path covers the collection read only. ENV_ID is a placeholder the deployment binds to a concrete environment before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "confluent.topics.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "confluent-cluster.invalid"
      ],
      "endpoint": "https://confluent-cluster.invalid/kafka/v3/clusters/CLUSTER_ID/topics",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-confluent-kafka-api-key",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "confluent-kafka-cluster",
      "description": "List the topics on one Kafka cluster: names, partition counts and configurations — metadata only, never message content. This endpoint is on the cluster's own Kafka REST host, not the management API host, and requires a resource-specific API key scoped to this cluster (see the credential note); the deployment substitutes the real per-cluster host and may override secret_ref_id per capability.\n\nThe registered path covers the collection read only. CLUSTER_ID is a placeholder the deployment binds before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "confluent.kafka_cluster.create",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R3",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "confluent-cloud.invalid"
      ],
      "endpoint": "https://confluent-cloud.invalid/cmk/v2/clusters",
      "method": "POST",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-confluent-cloud-api-key",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "create",
        "deploy"
      ],
      "resource_id": "confluent-environment",
      "description": "Create one Kafka cluster.\n\nThe request body is an unrestricted cluster spec — display name, cloud provider, region, availability and cluster type (Basic, Standard, Enterprise, Dedicated with CKU capacity) are all settable — so the registered capability carries the full create effect, including ongoing billed capacity; cost review belongs to the deployment's budget controls, not to this file. Provisioning is declarative and asynchronous (the API records intent and Confluent provisions to match).\n\nCreating a cluster provisions live, billable infrastructure, so the capability declares create and deploy at the minimum R3 tier — deploy is one of the designated actions requiring human approval — and an installer's intention to request only a Basic cluster is not a restriction the registration can enforce.\n\nOn supported AAES-mediated execution paths, the declared irreversible actions require an authorized person’s approval. Observation-only and bypass calls cannot be stopped by this control.",
      "requires_review": true
    },
    {
      "capability_id": "confluent.kafka_cluster.update",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R3",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "confluent-cloud.invalid"
      ],
      "endpoint": "https://confluent-cloud.invalid/cmk/v2/clusters/CLUSTER_ID",
      "method": "PATCH",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-confluent-cloud-api-key",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "update",
        "deploy"
      ],
      "resource_id": "confluent-environment",
      "description": "Update a Kafka cluster’s specification, including its display name or Dedicated-cluster CKU capacity. Resizing changes live, billed infrastructure. Confluent records the desired state and applies it asynchronously.\n\nRequest limits: the body is unrestricted within the update schema. The published OpenAPI specification, retrieved 2026-09-21, requires spec.environment in the body. PATCH takes no query parameters; GET and DELETE instead require an environment query parameter. Put the bound environment ID in spec.environment, not in a query string.\n\nClassification: update and deploy, minimum R3, because the operation can reconfigure live capacity. Bind ENV_ID and CLUSTER_ID before enabling.\n\nOn supported AAES-mediated execution paths, the declared irreversible actions require an authorized person’s approval. Observation-only and bypass calls cannot be stopped by this control.",
      "requires_review": true
    },
    {
      "capability_id": "confluent.kafka_cluster.delete",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R3",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "confluent-cloud.invalid"
      ],
      "endpoint": "https://confluent-cloud.invalid/cmk/v2/clusters/CLUSTER_ID?environment=ENV_ID",
      "method": "DELETE",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-confluent-cloud-api-key",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "delete"
      ],
      "resource_id": "confluent-environment",
      "description": "Delete a Kafka cluster. Deleting a cluster destroys every topic on it along with all message data, and re-creating a cluster later is a new cluster, not an undo of this call. Delete is one of the designated actions requiring human approval and registers at the minimum R3 tier.\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. ENV_ID and CLUSTER_ID are placeholders the deployment binds before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "confluent.topic.delete",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R3",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "confluent-cluster.invalid"
      ],
      "endpoint": "https://confluent-cluster.invalid/kafka/v3/clusters/CLUSTER_ID/topics/TOPIC_NAME",
      "method": "DELETE",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-confluent-kafka-api-key",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "delete"
      ],
      "resource_id": "confluent-kafka-cluster",
      "description": "Delete a topic. Deleting a topic destroys its messages and the producers' and consumers' target; a topic re-created under the same name is empty, not restored. Delete is one of the designated actions requiring human approval and registers at the minimum R3 tier.\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 endpoint is on the cluster's own Kafka REST host and requires a resource-specific API key scoped to this cluster (see the credential note). CLUSTER_ID and TOPIC_NAME are placeholders the deployment binds before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "confluent.api_key.delete",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R3",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "confluent-cloud.invalid"
      ],
      "endpoint": "https://confluent-cloud.invalid/iam/v2/api-keys/KEY_ID",
      "method": "DELETE",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-confluent-cloud-api-key",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "delete"
      ],
      "resource_id": "confluent-environment",
      "description": "Delete (revoke) an API key. Deleting a key permanently invalidates it for every integration using it — Confluent documents no undelete, and re-issuing produces a new key, not the old one — so this is the revocation path, not an undoable disable. Delete is one of the designated actions requiring human approval and registers at the minimum R3 tier.\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. Note the blast radius: a deployment must never bind this capability to the very key this pack's other capabilities authenticate with without a replacement already in place. API key CREATION is deliberately not registered by this pack; see the pack notes. KEY_ID is a placeholder the deployment binds before enabling.",
      "requires_review": true
    }
  ],
  "resources": [
    {
      "resource_id": "confluent-environment",
      "kind": "api",
      "locator": "https://confluent-cloud.invalid/org/v2/environments/ENV_ID",
      "data_class": "internal",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    },
    {
      "resource_id": "confluent-kafka-cluster",
      "kind": "api",
      "locator": "https://confluent-cluster.invalid/kafka/v3/clusters/CLUSTER_ID",
      "data_class": "internal",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    }
  ],
  "review": {
    "state": "library",
    "date": "2026-09-22",
    "sources": [
      "https://docs.confluent.io/cloud/current/api.html (retrieved 2026-09-21)",
      "https://docs.confluent.io/cloud/current/access-management/authenticate/api-keys/api-keys.html (retrieved 2026-09-21)",
      "https://docs.confluent.io/cloud/current/openapi.yaml (retrieved 2026-09-21)",
      "https://docs.confluent.io/cloud/current/kafka-rest/krest-qs.html (retrieved 2026-09-21)"
    ],
    "reviewer_id": "aaes-eng"
  }
}
