Maintaining Confluent RBAC

Manage Confluent RBAC rolebindings via YAML.

No ACL support. RBAC only.

YAML definition

Define principals and their permissions:

clients:
  - principal: User:app-consumer
    consumer_for:
      - topic: events.user.
      - topic: events.orders.
    groups:
      - name: app-consumer-group-

  - principal: User:app-producer
    producer_for:
      - topic: events.user.
        strict: true

  - principal: Group:data-engineers
    consumer_for:
      - topic: events.
      - topic: state.
    producer_for:
      - topic: analytics.

  - principal: User:admin
    resourceowner_for:
      - topic: events.critical.
        isLiteral: true

Principal format

Must be prefixed:

  • User:username

  • Group:groupname

Permission types

consumer_for

Read permission for topics and schema registry.

- principal: User:consumer-app
  consumer_for:
    - topic: events.orders.
    - topic: events.payments.
      isLiteral: false

Grants:

  • DeveloperRead on topics (default: prefixed)

  • DeveloperRead on schema registry subjects

producer_for

Write permission for topics and schema registry.

- principal: User:producer-app
  producer_for:
    - topic: events.orders.
      strict: false

Grants:

  • DeveloperWrite on topics (default: prefixed)

  • DeveloperWrite on schema registry subjects

Strict mode:

producer_for:
  - topic: events.orders.
    strict: true

Grants:

  • DeveloperWrite on topics

  • DeveloperRead on schema registry (read-only, no new schemas)

Use for production producers to prevent accidental schema changes.

resourceowner_for

Full ownership of topic.

- principal: User:topic-owner
  resourceowner_for:
    - topic: events.critical.
      isLiteral: true

Grants:

  • ResourceOwner role on topic

Topic pattern matching

By default, topic names are PREFIXED:

consumer_for:
  - topic: events.user.

Matches:

  • events.user.login

  • events.user.signup

  • events.user.anything

Literal matching:

consumer_for:
  - topic: events.user.login
    isLiteral: true

Matches only events.user.login.

Consumer groups

Grant access to consumer groups:

- principal: User:consumer-app
  consumer_for:
    - topic: events.orders.
  groups:
    - name: consumer-app-group-

Default role: DeveloperRead

Custom roles:

groups:
  - name: consumer-app-group-
    roles: ["ResourceOwner"]

Disable prefix matching:

groups:
  - name: exact-group-name
    prefixed: false

MDS configuration

In config.yaml:

connections:
  mds:
    url: "https://kafka:8090"
    username: "admin"
    password: "admin-secret"
    caPath: "/path/to/ca.crt"
    schema-registry-cluster-id: "schema-registry"
    connect-cluster-id: "connect-cluster"
    ksql-cluster-id: "ksql-cluster"

Cluster IDs required for cross-cluster rolebindings (e.g., schema registry permissions).

Complete examples

Consumer application

clients:
  - principal: User:order-processor
    consumer_for:
      - topic: events.orders.
      - topic: events.payments.
    groups:
      - name: order-processor-group-

Producer application

clients:
  - principal: User:api-gateway
    producer_for:
      - topic: events.user.
      - topic: events.orders.
        strict: true

Producer with idempotence

Idempotent producers need cluster-level write:

clients:
  - principal: User:idempotent-producer
    producer_for:
      - topic: events.orders.
        strict: true

Note: Idempotence requires DeveloperWrite on Cluster resource. Set via Confluent Control Center or MDS API.

Stream processor (consumer + producer)

clients:
  - principal: User:stream-processor
    consumer_for:
      - topic: events.raw.
    producer_for:
      - topic: events.processed.
    groups:
      - name: stream-processor-group-

Data engineer (broad read access)

clients:
  - principal: Group:data-engineers
    consumer_for:
      - topic: events.
      - topic: state.
      - topic: analytics.
    groups:
      - name: analytics-

Topic owner

clients:
  - principal: User:critical-app-owner
    resourceowner_for:
      - topic: events.critical.transactions
        isLiteral: true

Workflow

  1. Define principals in YAML

  2. Run gafkalo plan --config config.yaml

  3. Review rolebindings to be created

  4. Run gafkalo apply --config config.yaml

Gafkalo creates rolebindings via MDS REST API.

Best practices

  1. Use service accounts (User:) for applications

  2. Use groups (Group:) for teams

  3. Enable strict: true for production producers

  4. Use prefix matching for topic families

  5. Use literal matching for critical topics

  6. Separate read-only and write access

  7. Document principals in YAML comments

Limitations

  • No ACL support (RBAC only)

  • No rolebinding deletion (by design)

  • Predefined role combinations only (consumer, producer, resourceowner)

  • No custom role definitions

For advanced use cases, use Confluent Control Center or MDS API directly.

Troubleshooting

Principal not found

Ensure principal exists in authentication backend (LDAP, etc.).

Insufficient permissions

MDS user needs SystemAdmin or UserAdmin role.

Cluster ID mismatch

Verify cluster IDs in config match MDS configuration:

curl -u admin:password https://mds:8090/security/1.0/metadataClusterId