Skip to content

Preempt topic creation action with metadata list#1196

Open
rwaweber wants to merge 4 commits intoAiven-Open:mainfrom
rwaweber:preempt-topic-create
Open

Preempt topic creation action with metadata list#1196
rwaweber wants to merge 4 commits intoAiven-Open:mainfrom
rwaweber:preempt-topic-create

Conversation

@rwaweber
Copy link
Copy Markdown

In an ACL-enabled kafka environment trying to get karapace running as a schema registry, we ran into this hiccup since we aren't giving karapace full admin permissions.

Tracing down the topic authorization failure we were getting, it looks like karapace attempts topic creation before checking if the topic exists, then takes action based on that failure.

Instead, I think it makes sense to check the topic metadata before attempting to create the topic, as that's possible to do with a smaller, more scoped set of permissions.

About this change - What it does

  • Perform a topic list that match the config topic name before we try to create the schema storage topic

References: N/A (I figured a small patch may set the scene better than a bug report, but happy to create one if you all prefer!)

Why this way

In ACL-enabled kafka clusters, karapace would require a "CreateTopics" permission on the "Cluster" resource to complete this operation as-is. With these changes, the karapace identity only requires a "Describe" on a "Topic" resource with the "Metadata" API, which is easier to scope for an administrator perspective.

That being said, happy to consider alternative approaches, as I'm still pretty unfamiliar with this codebase at large!

@rwaweber rwaweber requested a review from a team as a code owner January 19, 2026 22:23
@muralibasani
Copy link
Copy Markdown
Contributor

@rwaweber thanks for the pr.
Can you fix lint (pre-commit run --all-files) and you may run smoke tests locally too

@rwaweber
Copy link
Copy Markdown
Author

Hey @muralibasani! Yeah absolutely, will hopefully get around to it tonight or this weekend!

@muralibasani
Copy link
Copy Markdown
Contributor

@rwaweber mypy check failed.

@rwaweber
Copy link
Copy Markdown
Author

Hey @muralibasani - so trying to run the mypy check locally, it seems like it does a bit more than just linting with the make type-check-mypy-in-docker command.

Looking at this line in the GHA run, I can't seem to suss out what exactly is going wrong in the docker compose setup. Do you have any suggestions on where I should be digging around to see?

@muralibasani
Copy link
Copy Markdown
Contributor

Hey @muralibasani - so trying to run the mypy check locally, it seems like it does a bit more than just linting with the make type-check-mypy-in-docker command.

Looking at this line in the GHA run, I can't seem to suss out what exactly is going wrong in the docker compose setup. Do you have any suggestions on where I should be digging around to see?

@rwaweber I tried running your branch/fork locally and schema registry fails to start and is unhealthy. _schemas topic is not created ?

karapace.core.schema_reader	schema-reader	WARNING 	Topic does not yet exist.
karapace.core.schema_reader	schema-reader	WARNING 	Topic does not yet exist.
karapace.core.schema_reader	schema-reader	WARNING 	Topic does not yet exist.
karapace.core.schema_reader	schema-reader	WARNING 	Topic does not yet exist.
karapace.core.schema_reader	schema-reader	WARNING 	Topic does not yet exist.
karapace.core.schema_reader	schema-reader	WARNING 	Topic does not yet exist.

@muralibasani muralibasani force-pushed the preempt-topic-create branch 2 times, most recently from e055eec to 3699e08 Compare March 2, 2026 08:09
@rwaweber
Copy link
Copy Markdown
Author

rwaweber commented Mar 5, 2026

That was super helpful, thanks @muralibasani! Found out I missed a pretty clear warning in the confluent-kafka docs:

Warning: If auto.create.topics.enable is set to true on the broker
and an unknown topic is specified, it will be created.

cite

I think that the "describe" call I'm introducing was accidentally creating the _schemas topic without compaction and things got a little weird from there in the tests. Updating this to listing all topics instead cleared things right up.

Also got the mypy tests to pass locally, so hopefully this go around fixes things!

@muralibasani
Copy link
Copy Markdown
Contributor

@rwaweber will look at it next week. Sorry.

@rwaweber
Copy link
Copy Markdown
Author

No need to apologize! I appreciate the collaboration, no rush at all!

@muralibasani muralibasani force-pushed the preempt-topic-create branch from 15897a5 to e1c86a5 Compare March 23, 2026 09:01
Comment thread src/karapace/core/schema_reader.py Outdated
schema_topic_exists = False
# Perform a metadata list, which is allowed in a describe permission, whereas
# topic-create permissions are a coarser permission grant, not typically given out
schema_topic_exists = self.config.topic_name in self.admin_client.list_topics().topics.keys()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If list_topics() fails because of any permission issues (Describe for ex), then we might run into failures.
Hence a try/catch with except TopicAuthorizationFailedError: ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good! In that instance, I'm thinking we handle the exception, set schema_topic_exists = False and then, just continue on or we raise to shortcircuit?

I'm just thinking practically, where one would grant a permission to be able to create a topic but deny listing topics on the cluster seems unlikely, but I could be oversimplifying.

rwaweber added 4 commits April 5, 2026 15:16
- Perform a get on topics that match the config topic name before we try
  to create the schema storage topic

- In ACL-enabled kafka clusters, karapace would require a "CreateTopics"
  permission on the "Cluster" resource to complete this operation as-is.
  With these changes, the karapace identity only requires a "Describe"
  on a "Topic" resource with the "Metadata" API, which is easier to
  scope for an administrator perspective.
- Not a big deal since we're just doing a containment operation
- Turns out I missed this warning on the list_topics operation:

> Warning: If auto.create.topics.enable is set to true on the broker
> and an unknown topic is specified, it will be created.

[cite](https://docs.confluent.io/platform/current/clients/confluent-kafka-python/html/index.html#confluent_kafka.admin.AdminClient.list_topics)
@rwaweber rwaweber force-pushed the preempt-topic-create branch from e1c86a5 to c6aac3b Compare April 6, 2026 01:17
LOG.warning(
"[Schema Topic] not authorized to list topics, assuming topic: %r does not exist",
self.config.topic_name
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add broader exception catch block too

except Exception:                                                                                                                 
      schema_topic_exists = False                                                                                                   
      LOG.warning(                                                                                                                  
          "[Schema Topic] failed to list topics, assuming topic: %r does not exist",                                                
          self.config.topic_name                                                                                                    
      )    

# Perform a metadata list, which is allowed in a describe permission, whereas
# topic-create permissions are a coarser permission grant, not typically given out
try:
schema_topic_exists = (
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a test for this extra check?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants