Apache Kafka · Arazzo Workflow

Apache Kafka Grant a Principal Access to a Topic

Version 1.0.0

Resolve the cluster, confirm the topic, audit existing ACLs, grant read access, and verify the grant.

1 workflow 1 source API 1 provider
View Spec View on GitHub Distributed SystemsEvent StreamingMessagingOpen SourcePub-SubArazzoWorkflows

Provider

apache-kafka

Workflows

grant-topic-access
Create and verify a topic READ ACL for a principal.
Confirms the topic, reviews existing topic ACLs, grants the principal read access, and verifies the resulting ACL set.
5 steps inputs: host, operation, patternType, permission, principal, topicName outputs: clusterId, existingAcls, resultingAcls, topicName
1
resolveCluster
listClusters
Resolve the cluster id so the ACL is written against the cluster the proxy is actually fronting.
2
confirmTopic
getTopic
Confirm the topic exists before writing an ACL against its name. Kafka accepts ACLs for topic names that do not exist, so a typo here would silently produce a grant that never takes effect.
3
auditExistingAcls
searchAcls
Audit the ACLs already bound to topic resources on this cluster, so the new grant is added with full knowledge of what access exists today.
4
createAcl
createAcls
Create the ACL binding the principal to the topic for the requested operation.
5
verifyAcl
searchAcls
Re-read the topic ACLs and confirm the grant is present, so the authorization change is proven by the cluster rather than assumed from a 201.

Source API Descriptions

Arazzo Workflow Specification

Raw ↑
arazzo: 1.0.1
info:
  title: Apache Kafka Grant a Principal Access to a Topic
  summary: Resolve the cluster, confirm the topic, audit existing ACLs, grant read access, and verify the grant.
  description: >-
    Onboarding a new consumer onto an existing topic is an authorization change,
    and it should be made against evidence rather than assumption. This workflow
    resolves the cluster, confirms the topic actually exists so the ACL is not
    written against a typo — Kafka will happily create an ACL for a topic name
    that does not exist — audits the ACLs already bound to the topic, creates
    the READ grant for the principal, and then re-reads the ACLs to prove the
    grant landed. Every step spells out its request inline so the flow can be
    read and executed without opening the underlying OpenAPI description.
  version: 1.0.0
sourceDescriptions:
- name: kafkaRestProxyApi
  url: ../openapi/kafka-rest-proxy.yml
  type: openapi
workflows:
- workflowId: grant-topic-access
  summary: Create and verify a topic READ ACL for a principal.
  description: >-
    Confirms the topic, reviews existing topic ACLs, grants the principal read
    access, and verifies the resulting ACL set.
  inputs:
    type: object
    required:
    - topicName
    - principal
    properties:
      topicName:
        type: string
        description: The topic the principal is being granted access to.
      principal:
        type: string
        description: >-
          The Kafka principal receiving the grant, in principal-type:name form
          (e.g. User:analytics-consumer).
      host:
        type: string
        description: >-
          The host the grant applies to. An asterisk allows the principal to
          connect from any host.
        default: '*'
      operation:
        type: string
        description: The operation being granted (e.g. READ, WRITE, DESCRIBE).
        default: READ
      permission:
        type: string
        description: Whether the ACL allows or denies the operation.
        default: ALLOW
      patternType:
        type: string
        description: >-
          How the resource name is matched. LITERAL binds the ACL to exactly
          this topic; PREFIXED would bind it to every topic sharing the prefix.
        default: LITERAL
  steps:
  - stepId: resolveCluster
    description: >-
      Resolve the cluster id so the ACL is written against the cluster the
      proxy is actually fronting.
    operationId: listClusters
    successCriteria:
    - condition: $statusCode == 200
    outputs:
      clusterId: $response.body#/data/0/cluster_id
  - stepId: confirmTopic
    description: >-
      Confirm the topic exists before writing an ACL against its name. Kafka
      accepts ACLs for topic names that do not exist, so a typo here would
      silently produce a grant that never takes effect.
    operationId: getTopic
    parameters:
    - name: cluster_id
      in: path
      value: $steps.resolveCluster.outputs.clusterId
    - name: topic_name
      in: path
      value: $inputs.topicName
    successCriteria:
    - condition: $statusCode == 200
    outputs:
      topicName: $response.body#/topic_name
      isInternal: $response.body#/is_internal
  - stepId: auditExistingAcls
    description: >-
      Audit the ACLs already bound to topic resources on this cluster, so the
      new grant is added with full knowledge of what access exists today.
    operationId: searchAcls
    parameters:
    - name: cluster_id
      in: path
      value: $steps.resolveCluster.outputs.clusterId
    - name: resource_type
      in: query
      value: TOPIC
    - name: pattern_type
      in: query
      value: ANY
    successCriteria:
    - condition: $statusCode == 200
    outputs:
      existingAcls: $response.body#/data
  - stepId: createAcl
    description: >-
      Create the ACL binding the principal to the topic for the requested
      operation.
    operationId: createAcls
    parameters:
    - name: cluster_id
      in: path
      value: $steps.resolveCluster.outputs.clusterId
    requestBody:
      contentType: application/json
      payload:
        resource_type: TOPIC
        resource_name: $steps.confirmTopic.outputs.topicName
        pattern_type: $inputs.patternType
        principal: $inputs.principal
        host: $inputs.host
        operation: $inputs.operation
        permission: $inputs.permission
    successCriteria:
    - condition: $statusCode == 201
  - stepId: verifyAcl
    description: >-
      Re-read the topic ACLs and confirm the grant is present, so the
      authorization change is proven by the cluster rather than assumed from a
      201.
    operationId: searchAcls
    parameters:
    - name: cluster_id
      in: path
      value: $steps.resolveCluster.outputs.clusterId
    - name: resource_type
      in: query
      value: TOPIC
    - name: pattern_type
      in: query
      value: LITERAL
    successCriteria:
    - condition: $statusCode == 200
    outputs:
      resultingAcls: $response.body#/data
  outputs:
    clusterId: $steps.resolveCluster.outputs.clusterId
    topicName: $steps.confirmTopic.outputs.topicName
    existingAcls: $steps.auditExistingAcls.outputs.existingAcls
    resultingAcls: $steps.verifyAcl.outputs.resultingAcls