confluentinc / terraform-provider-confluent

Terraform Provider for Confluent
Apache License 2.0
31 stars 64 forks source link

ksql service account can read ALL Kafka topics from a cluster without ACL assignment #113

Closed bluedog13 closed 2 years ago

bluedog13 commented 2 years ago

Below is my ksql app service account with the respective ACL's listed

$ confluent kafka acl list --service-account sa-ym8***

    Principal    | Permission |    Operation     |  Resource Type   |        Resource Name         | Pattern Type  
-----------------+------------+------------------+------------------+------------------------------+---------------
  User:sa-ym8*** | ALLOW      | DESCRIBE         | TOPIC            | *                            | LITERAL       
  User:sa-ym8*** | ALLOW      | DESCRIBE_CONFIGS | TOPIC            | *                            | LITERAL       
  User:sa-ym8*** | ALLOW      | ALL              | TOPIC            | _confluent-ksql-pksqlc-m51** | PREFIXED      
  User:sa-ym8*** | ALLOW      | ALL              | TOPIC            | pksqlc-m51**                 | PREFIXED      
  User:sa-ym8*** | ALLOW      | DESCRIBE         | GROUP            | *                            | LITERAL       
  User:sa-ym8*** | ALLOW      | DESCRIBE_CONFIGS | GROUP            | *                            | LITERAL       
  User:sa-ym8*** | ALLOW      | ALL              | GROUP            | _confluent-ksql-pksqlc-m51** | PREFIXED      
  User:sa-ym8*** | ALLOW      | DESCRIBE         | CLUSTER          | kafka-cluster                | LITERAL       
  User:sa-ym8*** | ALLOW      | DESCRIBE_CONFIGS | CLUSTER          | kafka-cluster                | LITERAL       
  User:sa-ym8*** | ALLOW      | WRITE            | TRANSACTIONAL_ID | pksqlc-m51**                 | LITERAL       
  User:sa-ym8*** | ALLOW      | DESCRIBE         | TRANSACTIONAL_ID | pksqlc-m51**                 | LITERAL 

However, I am able to read the contents from a topic it has no ACL to, when I connect to the ksql cluster and print the topic

#  Connect to ksql cluster using the ksql cli and above service account credentials
$ docker run --rm -it confluentinc/ksqldb-cli:0.27.1 ksql \
       -u [redacted] \
       -p [redacted] \
       "https://pksqlc-m51**.westus2.azure.confluent.cloud:443"

# Read from a topic in the Kafka cluster to which the service account has no access to
$ PRINT 'executable-[redacted]' FROM BEGINNING LIMIT 5;

---
Key format: HOPPING(KAFKA_STRING) or TUMBLING(KAFKA_STRING) or KAFKA_STRING
Value format: JSON or KAFKA_STRING
rowtime: 2022/09/21 21:42:41.334 Z, key: 
................................................
................................................

What is the expected behavior or am I missing something? Please help.

linouk23 commented 2 years ago

@bluedog13 could you double check that service account has no role bindings assigned?

bluedog13 commented 2 years ago

The service account does not have any other role bindings associated with it. This service account was created in Terraform and was only assigned the ACL's as shown above.

Could the problem be below? The ksql cluster has access to the kafka cluster/topics. So even though we connect to the ksql cluster using the service account/ksql cli, the fact that the ksql cluster has access to the kafka cluster - will not stop it from reading the topic data? Because if we can deploy new streams/tables that can read the topic data, why won't it not be possible to read the topic data?

linouk23 commented 2 years ago

cc @tolgadur

tolgadur commented 2 years ago

I am not sure I fully understand the question. You have wildcard DESCRIBE rights to all topics set with your service account. In other words, you can read data from all Kafka topics no matter the name, but not write to them. So what you're seeing should be expected behaviour?

That being said, your behaviour is not specific to terraform but to all ksqlDB clusters. If you create a ksqlDB cluster with the same service account in the UI you should be seeing the same behaviour if I understand the situation correctly.

tolgadur commented 2 years ago

Actually, I think you might be right. DESCRIBE shouldn't include READ operations. Sorry for the confusion! Could you share your terraform file so that we can try to help you further? cc. @luca-filipponi

bluedog13 commented 2 years ago

Thank for the reply.

From what I understand, the "DESCRIBE" ACL works at the Group/Topic Level and the "DESCRIBE_CONFIGS" work at the Topic level. And these two ACL's are different from the "READ" ACL on the topic.

So my question or confusion is (1) Why would a "DESCRIBE" ACL let the service account see/read all the messages inside the topic when there is no "READ" ACL defined?

(2) By having access to this service account, I can read ALL the messages from all the topics from the Kafka Cluster, which means this is a nice hack to get access to topics without needing to have any ACL. SInce Kafka does not support multi-tenancy, and if I have topics from multiple tenants in the same cluster - I now have access to ALL the topics in that cluster.

Thanks.

bluedog13 commented 2 years ago

@tolgadur

Unfortunately, I won't be able to share the .tf file since this is part of an enterprise project.

However I have followed the example that you guys have shared for the ksql ACL to create the ksql cluster and the ksqlDB service account. All the ACL's from line 96 to line 292 have been implemented.

tolgadur commented 2 years ago

We just tried to replicate this with the example ksql ACL and we couldn't replicate your issue.

Our service account ACLs are:

confluent kafka acl list --service-account sa-w5q3**                                                                                                                                                                                                                          ✔  1261  14:10:22
    Principal    | Permission |    Operation     |  Resource Type   |        Resource Name         | Pattern Type
-----------------+------------+------------------+------------------+------------------------------+---------------
  User:sa-w5q3dw | ALLOW      | DESCRIBE         | TOPIC            | *                            | LITERAL
  User:sa-w5q3dw | ALLOW      | DESCRIBE_CONFIGS | TOPIC            | *                            | LITERAL
  User:sa-w5q3dw | ALLOW      | ALL              | TOPIC            | _confluent-ksql-pksqlc-d8w81 | PREFIXED
  User:sa-w5q3dw | ALLOW      | ALL              | TOPIC            | pksqlc-d8w81                 | PREFIXED
  User:sa-w5q3dw | ALLOW      | ALL              | TOPIC            | users                        | PREFIXED
  User:sa-w5q3dw | ALLOW      | DESCRIBE         | GROUP            | *                            | LITERAL
  User:sa-w5q3dw | ALLOW      | DESCRIBE_CONFIGS | GROUP            | *                            | LITERAL
  User:sa-w5q3dw | ALLOW      | ALL              | GROUP            | _confluent-ksql-pksqlc-d8w81 | PREFIXED
  User:sa-w5q3dw | ALLOW      | DESCRIBE         | CLUSTER          | kafka-cluster                | LITERAL
  User:sa-w5q3dw | ALLOW      | DESCRIBE_CONFIGS | CLUSTER          | kafka-cluster                | LITERAL
  User:sa-w5q3dw | ALLOW      | WRITE            | TRANSACTIONAL_ID | pksqlc-d8w81                 | LITERAL
  User:sa-w5q3dw | ALLOW      | DESCRIBE         | TRANSACTIONAL_ID | pksqlc-d8w81                 | LITERAL

and when I try to access the bug topic that we created for this test it gives us:

ksql> PRINT 'bug' FROM BEGINNING LIMIT 5;
Authorization exception encountered while accessing Kafka: Authorization denied to Read on topic(s): [bug]
Please see the following documentation on how to properly set up ACLs for your ksqlDB application: https://docs.confluent.io/current/cloud/connect/ksql-cloud-config.html#create-acls-for-ksql-to-access-a-specific-topic-in-ccloud

Which API key and secret have you to run the docker ksql cli (i.e. docker run --rm -it confluentinc/ksqldb-cli:0.27.1 ksql \ -u [redacted] \ -p [redacted] \ "https://pksqlc-m51**.westus2.azure.confluent.cloud:443" )?

linouk23 commented 2 years ago

I'm closing this issue since it looks like one of our engineers didn't manage to reproduce this issue.