This is an automated email from the ASF dual-hosted git repository.
jshao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new a58a5f79b9 [#9336] improvement: Add documents for IRC authz (#9380)
a58a5f79b9 is described below
commit a58a5f79b9cd1a44cb609be6d50d7c9f1db42adb
Author: roryqi <[email protected]>
AuthorDate: Tue Dec 9 17:02:22 2025 +0800
[#9336] improvement: Add documents for IRC authz (#9380)
### What changes were proposed in this pull request?
Add documents for IRC authz
### Why are the changes needed?
Fix: #9336
### Does this PR introduce _any_ user-facing change?
No need.
### How was this patch tested?
Just documents.
---------
Co-authored-by: Copilot <[email protected]>
---
docs/iceberg-rest-service.md | 160 ++++++++++++++++++++++++++++++++++++++++
docs/security/access-control.md | 18 ++---
2 files changed, 169 insertions(+), 9 deletions(-)
diff --git a/docs/iceberg-rest-service.md b/docs/iceberg-rest-service.md
index 4ee4976658..c624c33b1b 100644
--- a/docs/iceberg-rest-service.md
+++ b/docs/iceberg-rest-service.md
@@ -28,6 +28,7 @@ There are some key difference between Gravitino Iceberg REST
server and Gravitin
- Supports event listener.
- Supports Audit log.
- Supports OAuth2 and HTTPS.
+- Supports access control (when running as an auxiliary service).
- Provides a pluggable metrics store interface to store and delete Iceberg
metrics.
- Supports table metadata cache.
@@ -284,6 +285,34 @@ The detailed configuration items are as follows:
Please refer to [Credential vending](./security/credential-vending.md) for
more details.
+### Access control
+
+#### Prerequisites
+
+To use access control with the Iceberg REST service:
+
+1. The Iceberg REST service must be running as an auxiliary service within the
Gravitino server (standalone mode is not supported for access control)
+2. Enable authorization in the Gravitino server by setting
`gravitino.authorization.enable = true`
+3. Use the [dynamic configuration
provider](#dynamic-catalog-configuration-provider) to retrieve catalog
configurations from Gravitino
+
+:::note
+Access control for the Iceberg REST Catalog (IRC) is only supported when
running as an auxiliary service embedded in the Gravitino server. Standalone
Iceberg REST server deployments do not support access control features.
+:::
+
+Please refer to [Access Control](./security/access-control.md) for details on
how to configure authorization, create roles, and grant privileges in Gravitino.
+
+#### How access control works
+
+When access control is enabled:
+
+1. Clients authenticate with the Iceberg REST service (Now we support Basic
auth and OAuth2)
+2. The Iceberg REST service sends the authenticated user identity, target
metadata object, and requested operation to the Gravitino server for
authorization verification
+3. Gravitino verifies the user has the necessary privileges to perform the
operation on the specified metadata object
+4. Upon successful authorization, the Iceberg REST service executes the
operation; otherwise, it returns an authorization error
+
+Please refer to [Access Control](./security/access-control.md) for the
complete list of privileges and how to grant them.
+
+
### Storage
#### S3 configuration
@@ -676,3 +705,134 @@ sh ./dev/docker/build-docker.sh --platform linux/arm64
--type iceberg-rest-serve
```
You could try Spark with Gravitino REST catalog service in our
[playground](./how-to-use-the-playground.md#using-apache-iceberg-rest-service).
+
+## Quick Start: Enable Access Control for Iceberg REST Server
+
+To enable access control for the Iceberg REST server using Gravitino's dynamic
configuration provider, follow these steps:
+
+### 1. Enable Authorization and Dynamic Config Provider
+
+Add the following to your Gravitino server configuration file
(`gravitino.conf`).
+Note that access control is only supported when running the Iceberg REST
server as an auxiliary service within the Gravitino server:
+
+```properties
+gravitino.authorization.enable = true
+gravitino.authorization.serviceAdmins = adminUser
+
+gravitino.iceberg-rest.catalog-config-provider = dynamic-config-provider
+gravitino.iceberg-rest.gravitino-uri = http://127.0.0.1:8090
+gravitino.iceberg-rest.gravitino-metalake = test
+```
+
+Restart the Iceberg REST server after updating the configuration.
+
+---
+
+### 2. Create a Metalake
+
+```shell
+curl -X POST -H "Accept: application/vnd.gravitino.v1+json" \
+-H "Content-Type: application/json" -d '{
+ "name": "test"
+}' http://localhost:8090/api/metalakes
+```
+
+---
+
+### 3. Create a Catalog
+
+```shell
+curl -X POST -H "Accept: application/vnd.gravitino.v1+json" \
+-H "Content-Type: application/json" -d '{
+ "name": "catalog1",
+ "type": "ICEBERG",
+ "comment": "Iceberg catalog",
+ "properties": {}
+}' http://localhost:8090/api/metalakes/test/catalogs
+```
+
+---
+
+### 4. Create a Role and Grant Privileges
+
+```shell
+curl -X POST -H "Accept: application/vnd.gravitino.v1+json" \
+-H "Content-Type: application/json" -d '{
+ "name": "role1",
+ "properties": {},
+ "securableObjects": [
+ {
+ "fullName": "catalog1",
+ "type": "CATALOG",
+ "privileges": [
+ {
+ "name": "USE_CATALOG",
+ "condition": "ALLOW"
+ },
+ {
+ "name": "USE_SCHEMA",
+ "condition": "ALLOW"
+ },
+ {
+ "name": "SELECT_TABLE",
+ "condition": "ALLOW"
+ }
+ ]
+ }
+ ]
+}' http://localhost:8090/api/metalakes/test/roles
+```
+
+---
+
+#### Verify Access is Denied Without Privileges
+
+Before granting any privileges, verify that the user cannot access the
catalog. Try to list tables as `user1` (replace with your actual authentication
method):
+
+```shell
+curl -u user1:password -H "Accept: application/vnd.gravitino.v1+json" \
+ http://localhost:9001/iceberg/v1/catalog1/namespaces/default/tables
+```
+
+This should return an error indicating insufficient privileges (such as HTTP
403 Forbidden).
+
+---
+
+#### Grant Role to User
+
+Now grant the role with privileges to the user:
+
+```shell
+curl -X PUT -H "Accept: application/vnd.gravitino.v1+json" \
+-H "Content-Type: application/json" -d '{
+ "roleNames": ["role1"]
+}' http://localhost:8090/api/metalakes/test/permissions/users/user1/grant
+```
+
+---
+
+#### Verify Access is Granted With Privileges
+
+After granting the role with privileges, repeat the request as `user1`:
+
+```shell
+curl -u user1:password -H "Accept: application/vnd.gravitino.v1+json" \
+ http://localhost:9001/iceberg/v1/catalog1/namespaces/default/tables
+```
+
+This time, the request should succeed and return the list of tables.
+
+---
+
+**Summary:**
+- Enable authorization and set configuration provider to
`dynamic-config-provider`
+- Create metalake
+- Create catalog
+- Create role and grant privileges
+- Assign role to user
+
+For more details, see the [Access Control
documentation](./security/access-control.md).
+
+> **Note:** IRC (Iceberg REST Catalog) authorization is not supported for
standalone Iceberg REST server deployments.
+> Access control features described here require the Iceberg REST server to be
run as an auxiliary service within the Gravitino server,
+> using the dynamic configuration provider. Standalone deployments do not
support IRC-based authorization.
diff --git a/docs/security/access-control.md b/docs/security/access-control.md
index 05760173e0..2c38887051 100644
--- a/docs/security/access-control.md
+++ b/docs/security/access-control.md
@@ -417,9 +417,9 @@ User user =
</TabItem>
</Tabs>
-### Delete a user
+### Remove a user
-You can delete a user by its name.
+You can remove a user by its name.
<Tabs groupId='language' queryString>
<TabItem value="shell" label="Shell">
@@ -434,7 +434,7 @@ curl -X DELETE -H "Accept:
application/vnd.gravitino.v1+json" \
```java
GravitinoClient client = ...
-boolean deleted =
+boolean removed =
client.removeUser("user1");
```
@@ -522,9 +522,9 @@ Group group =
</TabItem>
</Tabs>
-### Delete a group
+### Remove a group
-You can delete a group by its name.
+You can remove a group by its name.
<Tabs groupId='language' queryString>
<TabItem value="shell" label="Shell">
@@ -539,8 +539,8 @@ curl -X DELETE -H "Accept:
application/vnd.gravitino.v1+json" \
```java
GravitinoClient client = ...
-boolean deleted =
- client.deleteGroup("group1");
+boolean removed =
+ client.removeGroup("group1");
```
</TabItem>
@@ -1039,11 +1039,11 @@ The following table lists the required privileges for
each API.
| alter model version | First, you should have the privilege to
load the catalog and the schema. Then, you are one of the owners of the model,
schema, metalake, catalog.
|
| delete model version alias | First, you should have the privilege to
load the catalog and the schema. Then, you are one of the owners of the model,
schema, metalake, catalog.
|
| add user | `MANAGE_USERS` on the metalake or the
owner of the metalake
|
-| delete user | `MANAGE_USERS` on the metalake or the
owner of the metalake
|
+| remove user | `MANAGE_USERS` on the metalake or the
owner of the metalake
|
| get user | `MANAGE_USERS` on the metalake or the
owner of the metalake or himself
|
| list users | `MANAGE_USERS` on the metalake or the
owner of the metalake can see all the users, others can see himself
|
| add group | `MANAGE_GROUPS` on the metalake or the
owner of the metalake
|
-| delete group | `MANAGE_GROUPS` on the metalake or the
owner of the metalake
|
+| remove group | `MANAGE_GROUPS` on the metalake or the
owner of the metalake
|
| get group | `MANAGE_GROUPS` on the metalake or the
owner of the metalake or his groups
|
| list groups | `MANAGE_GROUPS` on the metalake or the
owner of the metalake can see all the groups, others can see his group
|
| create role | `CREATE_ROLE` on the metalake or the
owner of the metalake
|