This is an automated email from the ASF dual-hosted git repository.
dimas pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/polaris.git
The following commit(s) were added to refs/heads/main by this push:
new 2cfa41be5 Docs/improve idp documentation (#2695)
2cfa41be5 is described below
commit 2cfa41be5aab21694808ba851f85cdde8c8cecb5
Author: olsoloviov <[email protected]>
AuthorDate: Mon Sep 29 16:24:57 2025 +0100
Docs/improve idp documentation (#2695)
* Fix Github links in IDP documentation
* Separate IDP docs for usage and development
* - Add telemetry config example
- Fix link to getting started from landing page
- Fix mentioning role-arn as required
* Fix some relative links (local Hugo resolves them properly, but PR auto
checks still fails)
* Docs: narrow down --role-arn usage for AWS S3 only; fix a link in
keycloak guide.
* Docs: fix a link in keycloak guide.
---
client/python/cli/command/__init__.py | 2 -
client/python/cli/constants.py | 2 +-
site/content/_index.adoc | 2 +-
.../in-dev/unreleased/command-line-interface.md | 8 +-
.../creating-a-catalog/s3/_index.md | 2 +-
.../{using-polaris.md => using-polaris/_index.md} | 18 +--
.../using-polaris}/keycloak-idp.md | 8 +-
.../using-polaris/telemetry-tools.md | 70 ++++++++++++
.../in-dev/unreleased/managing-security/_index.md | 6 +-
.../managing-security/external-idp/_index.md | 110 +------------------
.../external-idp/idp-dev-notes.md | 122 +++++++++++++++++++++
site/content/in-dev/unreleased/telemetry.md | 4 +
12 files changed, 231 insertions(+), 123 deletions(-)
diff --git a/client/python/cli/command/__init__.py
b/client/python/cli/command/__init__.py
index 1aa6f1d81..d9c29f215 100644
--- a/client/python/cli/command/__init__.py
+++ b/client/python/cli/command/__init__.py
@@ -188,7 +188,5 @@ class Command(ABC):
"""
Used to validate a command. Should always be called before `execute`.
The arg parser will catch many issues
with options, but this is used to apply additional constraints that
the arg parser can't currently handle.
- One example is that a catalog cannot be created with the `s3` storage
type without a `--role-arn` option, but
- one can be created without this flag if it's using the `gcs` storage
type.
"""
raise Exception("`validate` called on abstract `Command`")
diff --git a/client/python/cli/constants.py b/client/python/cli/constants.py
index 44715d1f7..b3e937b46 100644
--- a/client/python/cli/constants.py
+++ b/client/python/cli/constants.py
@@ -227,7 +227,7 @@ class Hints:
"Multiple locations can be provided by specifying this option
more than once."
)
- ROLE_ARN = "(Only for S3) A role ARN to use when connecting to S3"
+ ROLE_ARN = "(Only for AWS S3) A role ARN to use when connecting to
S3"
EXTERNAL_ID = "(Only for S3) The external ID to use when
connecting to S3"
REGION = "(Only for S3) The region to use when connecting to S3"
USER_ARN = "(Only for S3) A user ARN to use when connecting to S3"
diff --git a/site/content/_index.adoc b/site/content/_index.adoc
index 8cdbfd7da..b493f0731 100644
--- a/site/content/_index.adoc
+++ b/site/content/_index.adoc
@@ -25,7 +25,7 @@ cascade:
{{< blocks/cover title="Welcome to the Apache Polaris™ (incubating) web site!"
image_anchor="center" color="primary" >}}
Apache Polaris is an open-source, fully-featured catalog for Apache Iceberg™.
It implements Iceberg's REST API, enabling seamless multi-engine
interoperability across a wide range of platforms, including Apache Doris™,
Apache Flink®, Apache Spark™, Dremio® OSS, StarRocks, and Trino.
-<a href="/in-dev/unreleased/getting-started/install-dependencies/" class="btn
btn-lg btn-dark mt-5">Get Started <i class="fas fa-arrow-alt-circle-right
ms-2"></i></a>
+<a href="/in-dev/unreleased/getting-started/" class="btn btn-lg btn-dark
mt-5">Get Started <i class="fas fa-arrow-alt-circle-right ms-2"></i></a>
{{< /blocks/cover >}}
diff --git a/site/content/in-dev/unreleased/command-line-interface.md
b/site/content/in-dev/unreleased/command-line-interface.md
index c191fe960..f89a9622d 100644
--- a/site/content/in-dev/unreleased/command-line-interface.md
+++ b/site/content/in-dev/unreleased/command-line-interface.md
@@ -133,8 +133,12 @@ options:
--type The type of catalog to create in [INTERNAL, EXTERNAL]. INTERNAL
by default.
--storage-type (Required) The type of storage to use for the catalog
--default-base-location (Required) Default base location of the catalog
+ --endpoint (Only for S3) The S3 endpoint to use when connecting to S3
+ --endpoint-internal (Only for S3) The S3 endpoint used by Polaris to
use when connecting to S3, if different from the one that clients use
+ --sts-endpoint (Only for S3) The STS endpoint to use when connecting to
STS
+ --path-style-access (Only for S3) Whether to use path-style-access for
S3
--allowed-location An allowed location for files tracked by the
catalog. Multiple locations can be provided by specifying this option more than
once.
- --role-arn (Required for S3) A role ARN to use when connecting to S3
+ --role-arn (Only for AWS S3) A role ARN to use when connecting to S3
--region (Only for S3) The region to use when connecting to S3
--external-id (Only for S3) The external ID to use when connecting to S3
--tenant-id (Required for Azure) A tenant ID to use when connecting to
Azure Storage
@@ -145,7 +149,7 @@ options:
--catalog-connection-type The type of external catalog in [ICEBERG,
HADOOP].
--iceberg-remote-catalog-name The remote catalog name when federating
to an Iceberg REST catalog
--hadoop-warehouse The warehouse to use when federating to a HADOOP
catalog
- --catalog-authentication-type The type of authentication in [OAUTH,
BEARER, SIGV4]
+ --catalog-authentication-type The type of authentication in [OAUTH,
BEARER, SIGV4, IMPLICIT]
--catalog-service-identity-type The type of service identity in
[AWS_IAM]
--catalog-service-identity-iam-arn When using the AWS_IAM service
identity type, this is the ARN of the IAM user or IAM role Polaris uses to
assume roles and then access external resources.
--catalog-uri The URI of the external catalog
diff --git
a/site/content/in-dev/unreleased/getting-started/creating-a-catalog/s3/_index.md
b/site/content/in-dev/unreleased/getting-started/creating-a-catalog/s3/_index.md
index 2bf78106f..538bca17a 100644
---
a/site/content/in-dev/unreleased/getting-started/creating-a-catalog/s3/_index.md
+++
b/site/content/in-dev/unreleased/getting-started/creating-a-catalog/s3/_index.md
@@ -32,7 +32,7 @@ For the `polaris catalogs create` [command]({{% ref
"../../../command-line-inter
```text
--storage-type s3
---role-arn (Required for S3) A role ARN to use when connecting to S3
+--role-arn (Only for AWS S3) A role ARN to use when connecting to S3
--region (Only for S3) The region to use when connecting to S3
--external-id (Only for S3) The external ID to use when connecting to S3
```
diff --git a/site/content/in-dev/unreleased/getting-started/using-polaris.md
b/site/content/in-dev/unreleased/getting-started/using-polaris/_index.md
similarity index 89%
rename from site/content/in-dev/unreleased/getting-started/using-polaris.md
rename to site/content/in-dev/unreleased/getting-started/using-polaris/_index.md
index 981c9fc35..a2e9f521a 100644
--- a/site/content/in-dev/unreleased/getting-started/using-polaris.md
+++ b/site/content/in-dev/unreleased/getting-started/using-polaris/_index.md
@@ -19,7 +19,7 @@
#
Title: Using Polaris
type: docs
-weight: 400
+weight: 401
---
## Setup
@@ -34,17 +34,17 @@ export CLIENT_SECRET=YOUR_CLIENT_SECRET
Refer to the [Creating a Catalog]({{% ref "creating-a-catalog" %}}) page for
instructions on defining a
catalog for your specific storage type. The following examples assume the
catalog's name is `quickstart_catalog`.
-In Polaris, the [catalog]({{% relref "../entities#catalog" %}}) is the
top-level entity that objects like [tables]({{% relref "../entities#table" %}})
and [views]({{% relref "../entities#view" %}}) are organized under.
+In Polaris, the [catalog]({{% relref "../../entities#catalog" %}}) is the
top-level entity that objects like [tables]({{% relref "../../entities#table"
%}}) and [views]({{% relref "../../entities#view" %}}) are organized under.
The `DEFAULT_BASE_LOCATION` value you provided at catalog creation time will
be the default location that objects in
this catalog should be stored in.
-Additionally, if Polaris is running somewhere other than `localhost:8181`, you
can specify the correct hostname and port by providing `--host` and `--port`
flags. For the full set of options supported by the CLI, please refer to the
[docs]({{% relref "../command-line-interface" %}}).
+Additionally, if Polaris is running somewhere other than `localhost:8181`, you
can specify the correct hostname and port by providing `--host` and `--port`
flags. For the full set of options supported by the CLI, please refer to the
[docs]({{% relref "../../command-line-interface" %}}).
### Creating a Principal and Assigning it Privileges
-With a catalog created, we can create a [principal]({{% relref
"../entities#principal" %}}) that has access to manage that catalog. For
details on how to configure the Polaris CLI, see [the section
above](#defining-a-catalog) or refer to the [docs]({{% relref
"../command-line-interface" %}}).
+With a catalog created, we can create a [principal]({{% relref
"../../entities#principal" %}}) that has access to manage that catalog. For
details on how to configure the Polaris CLI, see [the section
above](#defining-a-catalog) or refer to the [docs]({{% relref
"../../command-line-interface" %}}).
```shell
./polaris \
@@ -81,7 +81,7 @@ export USER_CLIENT_ID=XXXX
export USER_CLIENT_SECRET=YYYY
```
-Now, we grant the principal the [principal role]({{% relref
"../entities#principal-role" %}}) we created, and grant the [catalog role]({{%
relref "../entities#catalog-role" %}}) the principal role we created. For more
information on these entities, please refer to the linked documentation.
+Now, we grant the principal the [principal role]({{% relref
"../../entities#principal-role" %}}) we created, and grant the [catalog
role]({{% relref "../../entities#catalog-role" %}}) the principal role we
created. For more information on these entities, please refer to the linked
documentation.
```shell
./polaris \
@@ -106,7 +106,7 @@ Now, we’ve linked our principal to the catalog via roles
like so:

-In order to give this principal the ability to interact with the catalog, we
must assign some [privileges]({{% relref "../entities#privilege" %}}). For the
time being, we will give this principal the ability to fully manage content in
our new catalog. We can do this with the CLI like so:
+In order to give this principal the ability to interact with the catalog, we
must assign some [privileges]({{% relref "../../entities#privilege" %}}). For
the time being, we will give this principal the ability to fully manage content
in our new catalog. We can do this with the CLI like so:
```shell
./polaris \
@@ -120,7 +120,7 @@ In order to give this principal the ability to interact
with the catalog, we mus
CATALOG_MANAGE_CONTENT
```
-This grants the [catalog privileges]({{% relref "../entities#privilege" %}})
`CATALOG_MANAGE_CONTENT` to our catalog role, linking everything together like
so:
+This grants the [catalog privileges]({{% relref "../../entities#privilege"
%}}) `CATALOG_MANAGE_CONTENT` to our catalog role, linking everything together
like so:

@@ -334,7 +334,9 @@ curl -v
http://127.0.0.1:8181/api/management/v1/catalogs/quickstart_catalog -H "
```
## Next Steps
-* Visit [Configuring Polaris for Production]({{% relref
"../configuring-polaris-for-production" %}}).
+* Visit [Using Keycloak as the external identity provider]({{% relref
"keycloak-idp" %}}).
+* Visit [Using Polaris with telemetry tools]({{% relref "telemetry-tools" %}}).
+* Visit [Configuring Polaris for Production]({{% relref
"../../configuring-polaris-for-production" %}}).
* A Getting Started experience for using Spark with Jupyter Notebooks is
documented
[here](https://github.com/apache/polaris/blob/main/getting-started/spark/README.md).
* To shut down a locally-deployed Polaris server and clean up all related
Docker containers, run the command listed below. Cloud Deployments have their
respective termination commands on their Deployment page, while Polaris running
on Gradle will terminate when the Gradle process terminates.
```shell
diff --git
a/site/content/in-dev/unreleased/managing-security/external-idp/keycloak-idp.md
b/site/content/in-dev/unreleased/getting-started/using-polaris/keycloak-idp.md
similarity index 97%
rename from
site/content/in-dev/unreleased/managing-security/external-idp/keycloak-idp.md
rename to
site/content/in-dev/unreleased/getting-started/using-polaris/keycloak-idp.md
index 1a9cdad48..a0d27b738 100644
---
a/site/content/in-dev/unreleased/managing-security/external-idp/keycloak-idp.md
+++
b/site/content/in-dev/unreleased/getting-started/using-polaris/keycloak-idp.md
@@ -17,12 +17,14 @@
# specific language governing permissions and limitations
# under the License.
#
-title: Using Polaris with Keycloak as external IDP
+title: Getting Started with Apache Polaris, External Authentication and
Keycloak
linkTitle: Using Keycloak IDP
type: docs
-weight: 100
+weight: 400
---
+## Overview
+
This example uses Keycloak as an **external** identity provider for Polaris.
The "iceberg" realm is automatically
created and configured from the `iceberg-realm.json` file.
@@ -48,7 +50,7 @@ Polaris is configured with 3 realms:
issued by both Polaris and Keycloak.
For more information about how to configure Polaris with external
authentication, see the
-[Polaris documentation]({{% ref "../external-idp" %}}).
+[IDP integration documentation]({{% relref
"../../managing-security/external-idp" %}}).
## Starting the Example
diff --git
a/site/content/in-dev/unreleased/getting-started/using-polaris/telemetry-tools.md
b/site/content/in-dev/unreleased/getting-started/using-polaris/telemetry-tools.md
new file mode 100644
index 000000000..b6a9e8f8e
--- /dev/null
+++
b/site/content/in-dev/unreleased/getting-started/using-polaris/telemetry-tools.md
@@ -0,0 +1,70 @@
+---
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+title: Getting Started with Apache Polaris, Prometheus and Jaeger
+linkTitle: Using Polaris with telemetry tools
+type: docs
+weight: 401
+---
+
+This example requires `jq` to be installed on your machine.
+
+1. Build the Polaris image if it's not already present locally:
+
+ ```shell
+ ./gradlew \
+ :polaris-server:assemble \
+ :polaris-server:quarkusAppPartsBuild --rerun \
+ -Dquarkus.container-image.build=true
+ ```
+
+2. Start the docker compose group by running the following command from the
root of the repository:
+
+ ```shell
+ export ASSETS_PATH=$(pwd)/getting-started/assets/
+ export CLIENT_ID=root
+ export CLIENT_SECRET=s3cr3t
+ docker compose -f getting-started/telemetry/docker-compose.yml up
+ ```
+
+3. To access Polaris from the host machine, first request an access token:
+
+ ```shell
+ export POLARIS_TOKEN=$(curl -s
http://localhost:8181/api/catalog/v1/oauth/tokens \
+ --user root:s3cr3t \
+ -d 'grant_type=client_credentials' \
+ -d 'scope=PRINCIPAL_ROLE:ALL' | jq -r .access_token)
+ ```
+
+4. Then, use the access token in the Authorization header when accessing
Polaris; you can also test
+ the `Polaris-Request-Id` header; you should see it in all logs and traces:
+
+ ```shell
+ curl -v 'http://localhost:8181/api/management/v1/principal-roles' \
+ -H "Authorization: Bearer $POLARIS_TOKEN" \
+ -H "Polaris-Request-Id: 1234"
+ curl -v
'http://localhost:8181/api/catalog/v1/config?warehouse=quickstart_catalog' \
+ -H "Authorization: Bearer $POLARIS_TOKEN" \
+ -H "Polaris-Request-Id: 5678"
+ ```
+
+5. Access the following services:
+
+ - Prometheus UI: browse to http://localhost:9093 to view metrics.
+ - Jaeger UI: browse to http://localhost:16686 to view traces.
diff --git a/site/content/in-dev/unreleased/managing-security/_index.md
b/site/content/in-dev/unreleased/managing-security/_index.md
index d96c870c5..3a10c8900 100644
--- a/site/content/in-dev/unreleased/managing-security/_index.md
+++ b/site/content/in-dev/unreleased/managing-security/_index.md
@@ -20,5 +20,9 @@
title: Managing Security
linkTitle: Managing Security
type: docs
-weight: 1001
+weight: 550
---
+
+## [Access Control]({{< relref "access-control" >}})
+
+## [Authentification and Identity Providers]({{< relref "external-idp" >}})
\ No newline at end of file
diff --git
a/site/content/in-dev/unreleased/managing-security/external-idp/_index.md
b/site/content/in-dev/unreleased/managing-security/external-idp/_index.md
index 6767924c5..0b236cf31 100644
--- a/site/content/in-dev/unreleased/managing-security/external-idp/_index.md
+++ b/site/content/in-dev/unreleased/managing-security/external-idp/_index.md
@@ -51,7 +51,7 @@ polaris.authentication.realm2.type=mixed
### Authenticator
-The
[`Authenticator`](https://github.com/apache/polaris/blob/main/service/common/src/main/java/org/apache/polaris/service/auth/Authenticator.java)
is a component responsible for resolving the principal and the principal
roles, and for creating a `PolarisPrincipal` from the credentials provided by
the authentication process. It is a central component and is invoked for all
types of authentication.
+The `Authenticator` is a component responsible for resolving the principal and
the principal roles, and for creating a `PolarisPrincipal` from the credentials
provided by the authentication process. It is a central component and is
invoked for all types of authentication.
The `type` property is used to define the `Authenticator` implementation. It
is overridable per realm:
@@ -64,7 +64,7 @@ polaris.authentication.realm1.authenticator.type=custom
### Token Broker
-The
[`TokenBroker`](https://github.com/apache/polaris/blob/main/service/common/src/main/java/org/apache/polaris/service/auth/TokenBroker.java)
signs and verifies tokens to ensure that they can be validated and remain
unaltered.
+The `TokenBroker` signs and verifies tokens to ensure that they can be
validated and remain unaltered.
```properties
polaris.authentication.token-broker.type=rsa-key-pair
@@ -138,7 +138,7 @@ quarkus.oidc.oidc-tenant1.client-id=client1
quarkus.oidc.oidc-tenant1.application-type=service
```
-When using multiple OIDC tenants, it's your responsibility to configure tenant
resolution appropriately. See the [Quarkus OpenID Connect Multitenany
Guide](https://quarkus.io/guides/security-openid-connect-multitenancy#tenant-resolution).
+When using multiple OIDC tenants, it's your responsibility to configure tenant
resolution appropriately. See the [Quarkus OpenID Connect Multitenancy
Guide](https://quarkus.io/guides/security-openid-connect-multitenancy#tenant-resolution).
### Principal Mapping
@@ -196,105 +196,6 @@
polaris.oidc.principal-roles-mapper.mappings[0].replacement=PRINCIPAL_ROLE:$1
```
See more examples below.
-
-## Developer Architecture Notes
-
-The following sections describe internal implementation details for developers
who want to understand or extend Polaris authentication.
-
-### Authentication Architecture
-
-Polaris separates authentication into two logical phases using [Quarkus
Security](https://quarkus.io/guides/security-overview):
-
-1. Credential extraction – parsing headers and tokens
-2. Credential authentication – validating identity and assigning roles
-
-### Key Interfaces
-
--
[`Authenticator`](https://github.com/apache/polaris/blob/main/service/common/src/main/java/org/apache/polaris/service/auth/Authenticator.java):
A core interface used to authenticate credentials and resolve principal and
principal roles. Roles may be derived from OIDC claims or internal mappings.
--
[`DecodedToken`](https://github.com/apache/polaris/blob/main/service/common/src/main/java/org/apache/polaris/service/auth/DecodedToken.java):
Used in internal auth and inherits from `PrincipalCredential`.
-
-- The
[`DefaultAuthenticator`](https://github.com/apache/polaris/blob/main/service/common/src/main/java/org/apache/polaris/service/auth/DefaultAuthenticator.java)
is used to implement realm-specific logic based on these abstractions.
-
-### Token Broker Configuration
-
-When internal authentication is enabled, Polaris uses token brokers to handle
the decoding and validation of authentication tokens. These brokers are
request-scoped and can be configured per realm. Each realm may use its own
strategy, such as RSA key pairs or shared secrets, depending on security
requirements.
-
-## Developer Authentication Workflows
-
-### Internal Authentication
-
-1.
[`InternalAuthenticationMechanism`](https://github.com/apache/polaris/blob/main/runtime/service/src/main/java/org/apache/polaris/service/quarkus/auth/internal/InternalAuthenticationMechanism.java)
parses the auth header.
-2. Uses
[`TokenBroker`](https://github.com/apache/polaris/blob/main/service/common/src/main/java/org/apache/polaris/service/auth/TokenBroker.java)
to decode the token.
-3. Builds
[`PrincipalAuthInfo`](https://github.com/apache/polaris/blob/main/service/common/src/main/java/org/apache/polaris/service/auth/PrincipalAuthInfo.java)
and generates `SecurityIdentity` (Quarkus).
-4. `Authenticator.authenticate()` validates the credential, resolves the
principal and principal roles, then creates the `PolarisPrincipal`.
-
-### External Authentication
-
-1. `OidcAuthenticationMechanism` (Quarkus) processes the auth header.
-2.
[`OidcTenantResolvingAugmentor`](https://github.com/apache/polaris/blob/main/runtime/service/src/main/java/org/apache/polaris/service/quarkus/auth/external/OidcTenantResolvingAugmentor.java)
selects the OIDC tenant.
-3.
[`PrincipalAuthInfoAugmentor`](https://github.com/apache/polaris/blob/main/runtime/service/src/main/java/org/apache/polaris/service/quarkus/auth/external/PrincipalAuthInfoAugmentor.java)
extracts JWT claims.
-4. `Authenticator.authenticate()` validates the claims, resolves the principal
and principal roles, then creates the `PolarisPrincipal`.
-
-### Mixed Authentication
-
-1.
[`InternalAuthenticationMechanism`](https://github.com/apache/polaris/blob/main/runtime/service/src/main/java/org/apache/polaris/service/quarkus/auth/internal/InternalAuthenticationMechanism.java)
tries decoding.
-2. If successful, proceed with internal authentication.
-3. Otherwise, fall back to external (OIDC) authentication.
-
-## OIDC Configuration Reference
-
-### Principal Mapping
-
-- Interface:
[`PrincipalMapper`](https://github.com/apache/polaris/blob/main/runtime/service/src/main/java/org/apache/polaris/service/quarkus/auth/external/mapping/PrincipalMapper.java)
-
- The `PrincipalMapper` is responsible for extracting the Polaris principal ID
and display name from OIDC tokens.
-
-- Implementation selector:
-
- This property selects the implementation of the `PrincipalMapper` interface.
The default implementation extracts fields from specific claim paths.
-
- ```properties
- polaris.oidc.principal-mapper.type=default
- ```
-
-- Configuration properties for the default implementation:
-
- ```properties
- polaris.oidc.principal-mapper.id-claim-path=polaris/principal_id
- polaris.oidc.principal-mapper.name-claim-path=polaris/principal_name
- ```
-
-- It can be overridden per OIDC tenant.
-
-### Roles Mapping
-
-- Interface:
[`PrincipalRolesMapper`](https://github.com/apache/polaris/blob/main/runtime/service/src/main/java/org/apache/polaris/service/quarkus/auth/external/mapping/PrincipalRolesMapper.java)
-
- Polaris uses this component to transform role claims from OIDC tokens into
Polaris roles.
-
-- Quarkus OIDC configuration:
-
- This setting instructs Quarkus on where to locate roles within the OIDC
token.
-
- ```properties
- quarkus.oidc.roles.role-claim-path=polaris/roles
- ```
-
-- Implementation selector:
-
- This property selects the implementation of `PrincipalRolesMapper`. The
`default` implementation applies regular expression (regex) transformations to
OIDC roles.
-
- ```properties
- polaris.oidc.principal-roles-mapper.type=default
- ```
-
-- Configuration properties for the default implementation:
-
- ```properties
- polaris.oidc.principal-roles-mapper.filter=^(?!profile$|email$).*
- polaris.oidc.principal-roles-mapper.mappings[0].regex=^.*$
- polaris.oidc.principal-roles-mapper.mappings[0].replacement=PRINCIPAL_ROLE:$0
- ```
### Example JWT Mappings
@@ -348,6 +249,7 @@ When internal authentication is enabled, Polaris uses token
brokers to handle th
Polaris roles: `PRINCIPAL_ROLE:service_admin` and
`PRINCIPAL_ROLE:catalog_admin`
-### Additional Examples
+### Additional Links
-For complete Keycloak integration example, see: [Keycloak External IDP
Configuration Guide]({{< relref "keycloak-idp.md" >}})
\ No newline at end of file
+* For complete Keycloak integration example, see: [Keycloak External IDP
Configuration Guide]({{< relref "keycloak-idp.md" >}})
+* See [Developer Notes]({{< relref "idp-dev-notes.md" >}}) with internal
implementation details for developers who want to understand or extend Polaris
authentication.
\ No newline at end of file
diff --git
a/site/content/in-dev/unreleased/managing-security/external-idp/idp-dev-notes.md
b/site/content/in-dev/unreleased/managing-security/external-idp/idp-dev-notes.md
new file mode 100644
index 000000000..16bc759b8
--- /dev/null
+++
b/site/content/in-dev/unreleased/managing-security/external-idp/idp-dev-notes.md
@@ -0,0 +1,122 @@
+---
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+title: Authentification Development Details
+linkTitle: Development Details
+type: docs
+weight: 301
+---
+
+## Developer Architecture Notes
+
+### Authentication Architecture
+
+Polaris separates authentication into two logical phases using [Quarkus
Security](https://quarkus.io/guides/security-overview):
+
+1. Credential extraction – parsing headers and tokens
+2. Credential authentication – validating identity and assigning roles
+
+### Key Interfaces
+
+-
[`Authenticator`](https://github.com/apache/polaris/blob/main/runtime/service/src/main/java/org/apache/polaris/service/auth/Authenticator.java):
A core interface used to authenticate credentials and resolve principal and
principal roles. Roles may be derived from OIDC claims or internal mappings.
+-
[`InternalPolarisToken`](https://github.com/apache/polaris/blob/main/runtime/service/src/main/java/org/apache/polaris/service/auth/InternalPolarisToken.java):
Used in internal auth and inherits from `PrincipalCredential`.
+
+- The
[`DefaultAuthenticator`](https://github.com/apache/polaris/blob/main/runtime/service/src/main/java/org/apache/polaris/service/auth/DefaultAuthenticator.java)
is used to implement realm-specific logic based on these abstractions.
+
+### Token Broker Configuration
+
+When internal authentication is enabled, Polaris uses
[`TokenBroker`](https://github.com/apache/polaris/blob/main/runtime/service/src/main/java/org/apache/polaris/service/auth/TokenBroker.java)
to handle the decoding and validation of authentication tokens. These brokers
are request-scoped and can be configured per realm. Each realm may use its own
strategy, such as RSA key pairs or shared secrets, depending on security
requirements.
+See [Token Broker description]({{< relref "../external-idp#token-broker" >}})
for configuration details.
+
+## Developer Authentication Workflows
+
+### Internal Authentication
+
+1.
[`InternalAuthenticationMechanism`](https://github.com/apache/polaris/blob/main/runtime/service/src/main/java/org/apache/polaris/service/auth/internal/InternalAuthenticationMechanism.java)
parses the auth header.
+2. Uses
[`TokenBroker`](https://github.com/apache/polaris/blob/main/runtime/service/src/main/java/org/apache/polaris/service/auth/TokenBroker.java)
to decode the token.
+3. Builds
[`InternalAuthenticationRequest`](https://github.com/apache/polaris/blob/main/runtime/service/src/main/java/org/apache/polaris/service/auth/internal/InternalAuthenticationRequest.java)
and generates `SecurityIdentity` (Quarkus).
+4. `Authenticator.authenticate()` validates the credential, resolves the
principal and principal roles, then creates the `PolarisPrincipal`.
+
+### External Authentication
+
+1. `OidcAuthenticationMechanism` (Quarkus) processes the auth header.
+2.
[`OidcTenantResolvingAugmentor`](https://github.com/apache/polaris/blob/main/runtime/service/src/main/java/org/apache/polaris/service/auth/external/tenant/OidcTenantResolvingAugmentor.java)
selects the OIDC tenant.
+3.
[`OidcPolarisCredentialAugmentor`](https://github.com/apache/polaris/blob/main/runtime/service/src/main/java/org/apache/polaris/service/auth/external/OidcPolarisCredentialAugmentor.java)
extracts JWT claims.
+4. `Authenticator.authenticate()` validates the claims, resolves the principal
and principal roles, then creates the `PolarisPrincipal`.
+
+### Mixed Authentication
+
+1.
[`InternalAuthenticationMechanism`](https://github.com/apache/polaris/blob/main/runtime/service/src/main/java/org/apache/polaris/service/auth/internal/InternalAuthenticationMechanism.java)
tries decoding.
+2. If successful, proceed with internal authentication.
+3. Otherwise, fall back to external (OIDC) authentication.
+
+## OIDC Configuration Reference
+
+### Principal Mapping
+
+- Interface:
[`PrincipalMapper`](https://github.com/apache/polaris/blob/main/runtime/service/src/main/java/org/apache/polaris/service/auth/external/mapping/PrincipalMapper.java)
+
+ The `PrincipalMapper` is responsible for extracting the Polaris principal ID
and display name from OIDC tokens.
+
+- Implementation selector:
+
+ This property selects the implementation of the `PrincipalMapper` interface.
The default implementation extracts fields from specific claim paths.
+
+ ```properties
+ polaris.oidc.principal-mapper.type=default
+ ```
+
+- Configuration properties for the default implementation:
+
+ ```properties
+ polaris.oidc.principal-mapper.id-claim-path=polaris/principal_id
+ polaris.oidc.principal-mapper.name-claim-path=polaris/principal_name
+ ```
+
+- It can be overridden per OIDC tenant.
+
+### Roles Mapping
+
+- Interface:
[`PrincipalRolesMapper`](https://github.com/apache/polaris/blob/main/runtime/service/src/main/java/org/apache/polaris/service/auth/external/mapping/PrincipalRolesMapper.java)
+
+ Polaris uses this component to transform role claims from OIDC tokens into
Polaris roles.
+
+- Quarkus OIDC configuration:
+
+ This setting instructs Quarkus on where to locate roles within the OIDC
token.
+
+ ```properties
+ quarkus.oidc.roles.role-claim-path=polaris/roles
+ ```
+
+- Implementation selector:
+
+ This property selects the implementation of `PrincipalRolesMapper`. The
`default` implementation applies regular expression (regex) transformations to
OIDC roles.
+
+ ```properties
+ polaris.oidc.principal-roles-mapper.type=default
+ ```
+
+- Configuration properties for the default implementation:
+
+ ```properties
+ polaris.oidc.principal-roles-mapper.filter=^(?!profile$|email$).*
+ polaris.oidc.principal-roles-mapper.mappings[0].regex=^.*$
+ polaris.oidc.principal-roles-mapper.mappings[0].replacement=PRINCIPAL_ROLE:$0
+ ```
diff --git a/site/content/in-dev/unreleased/telemetry.md
b/site/content/in-dev/unreleased/telemetry.md
index 9e867408d..13b282378 100644
--- a/site/content/in-dev/unreleased/telemetry.md
+++ b/site/content/in-dev/unreleased/telemetry.md
@@ -190,3 +190,7 @@ polaris.log.mdc.region=us-west-2
```
MDC context is propagated across threads, including in `TaskExecutor` threads.
+
+## Links
+
+Visit [Using Polaris with telemetry tools]({{% relref "telemetry-tools" %}})
to see sample Polaris config with Prometheus and Jaeger.