Skip to content

[FEATURE] Kafka: add principal field to operation binding for ACL documentation #302

Open
asyncapi/spec-json-schemas
#645

Description

@ivangsa

Why do we need this improvement?

Kafka access is controlled via ACLs, but there is no way to document which
principal an operation requires in an AsyncAPI document. Teams have to look
outside the spec to find out what service account to use and what permissions
to request.

How will this change help?

The principal and its required permission become part of the contract.
The permission direction is already implicit in the operation action:
send implies write, receive implies read.

Tooling that generates Kafka ACLs or RBAC assignments from AsyncAPI documents
can derive the full access rule from the operation alone.

Screenshots

No response

How could it be implemented/designed?

Add a single principal string field to the Operation Binding Object.

Field Name Type Description Applicability [default] Constraints
principal string The Kafka principal (service account or user) that requires access to perform this operation. OPTIONAL The implied permission is write for send operations and read for receive operations.

Example:

operations:
  publishPaymentEvent:
    action: send
    bindings:
      kafka:
        principal: 'payments-service'
        bindingVersion: '0.6.0'
 
  consumePaymentEvents:
    action: receive
    bindings:
      kafka:
        principal: 'payments-service'
        bindingVersion: '0.6.0'

In spec-json-schemas, the addition to operation.json is straightforward:

"principal": {
  "type": "string",
  "description": "The Kafka principal (service account or user) that requires access to perform this operation. The implied permission is write for send operations and read for receive operations."
}

🚧 Breaking changes

No

👀 Have you checked for similar open issues?

  • I checked and didn't find a similar issue

🏢 Have you read the Contributing Guidelines?

Are you willing to work on this issue?

Yes I am willing to submit a PR!

Activity

  1. changed the title [-][FEATURE] add principal field to operation binding for ACL documentation[/-] [+][FEATURE] Kafka: add principal field to operation binding for ACL documentation[/+] on Jun 4, 2026
  2. dalelane commented on Jun 5, 2026

    @dalelane
    Collaborator

    Would you mind describing the motivation for this a little more, please?

    I see AsyncAPI as a good place to describe the characteristics of an application needed to access a Kafka topic. In a security context, that means we use it to detail the permissions needed. (A lot of the ACLs can just be derived from the operations, but this can be fleshed out once we have things like transactional id covered) But I'm struggling to think of a time when specifying the specific userid would be needed.

    If your assumption is that an AsyncAPI doc uniquely documents a single application, and your focus is in enabling generation of everything from a spec, then could it not be sufficient to adopt a convention where the principal is derived from the AsyncAPI id?

  3. ivangsa commented on Jun 9, 2026

    @ivangsa
    Author

    Yes, for ACL generation the principal is still needed explicitly.

    For example, depending on the operation/runtime semantics, tooling may need to grant access to:

    • principal (for writing)
    • principal + groupId (for reading)
    • principal + transactionalId

    (I hadn't realized transactionalId also needs ACLs, but that is being discussed in the other issue.)

    I agree that principal is probably common for the whole application in most cases, and then overridden only for specific operations when needed.

    But I would not infer it from the application id. The AsyncAPI id is a URI, while a Kafka principal is a security identity / service account. They are related concepts, but not the same thing, and deriving one from the other feels too implicit for ACL generation.

    The shape I would prefer is probably:

    operations:
      consumePaymentEvents:
        action: receive
        bindings:
          kafka:
            principal: User:payments-service
            groupId:
              const: payments-consumer-group

    The only awkward part is that AsyncAPI does not currently have global API-level bindings, so there is no natural place to define a default Kafka principal once for the whole application and override it per operation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions