Skip to content

Commit 92535f1

Browse files
committed
add authentication with bearer token
1 parent c448ebc commit 92535f1

15 files changed

Lines changed: 576 additions & 44 deletions

File tree

Cargo.lock

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.nix

Lines changed: 18 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crate-hashes.json

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

deploy/helm/spark-k8s-operator/templates/roles.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,24 @@ rules:
193193
- get
194194
- list
195195
- watch
196+
# OpenLineage backend connections referenced by SparkApplications.
197+
- apiGroups:
198+
- openlineage.stackable.tech
199+
resources:
200+
- openlineageconnections
201+
verbs:
202+
- get
203+
- list
204+
- watch
205+
# AuthenticationClasses used to authenticate against an OpenLineage backend.
206+
- apiGroups:
207+
- authentication.stackable.tech
208+
resources:
209+
- authenticationclasses
210+
verbs:
211+
- get
212+
- list
213+
- watch
196214
# Required for managing how the History Server and Connect Server are exposed
197215
# outside of the cluster.
198216
- apiGroups:

docs/modules/spark-k8s/pages/usage-guide/openlineage.adoc

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,65 @@ trust store, so the OpenLineage listener trusts the backend's certificate.
6868

6969
You can still override any of the injected values — including the full `spark.openlineage.transport.url` — through `sparkConf`.
7070

71+
[#authentication]
72+
== Authentication
73+
74+
Backends that require authentication (for example DataHub, or a Marquez instance behind a gateway) expect a bearer token on each request.
75+
Configure this by referencing an xref:concepts:authentication.adoc[`AuthenticationClass`] from the connection via `authenticationClassRef`:
76+
77+
[source,yaml]
78+
----
79+
apiVersion: spark.stackable.tech/v1alpha1
80+
kind: SparkApplication
81+
metadata:
82+
name: orders-by-nation
83+
spec:
84+
openLineage:
85+
connection:
86+
inline:
87+
host: marquez
88+
port: 5000
89+
authenticationClassRef: openlineage-auth # <1>
90+
...
91+
---
92+
apiVersion: authentication.stackable.tech/v1alpha1
93+
kind: AuthenticationClass
94+
metadata:
95+
name: openlineage-auth
96+
spec:
97+
provider:
98+
static: # <2>
99+
userCredentialsSecret:
100+
name: openlineage-token # <3>
101+
---
102+
apiVersion: v1
103+
kind: Secret
104+
metadata:
105+
name: openlineage-token
106+
namespace: default # <4>
107+
stringData:
108+
apiKey: "s3cr3t-bearer-token" # <5>
109+
----
110+
<1> References an `AuthenticationClass` by name (cluster-scoped). If omitted, no authentication is used.
111+
<2> Only the `static` provider is supported for OpenLineage. Other providers (LDAP, OIDC, TLS) are rejected with an error.
112+
<3> Name of the Secret holding the token. Must exist in the same namespace as the `SparkApplication`.
113+
<4> The Secret must be in the workload's namespace so it can be projected into the driver.
114+
<5> The token must be stored under the fixed key `apiKey`. The operator never reads the Secret; it is injected into the driver's OpenLineage listener via a `secretKeyRef` environment variable, so the token never appears in the spark-submit arguments or the pod spec.
115+
116+
The operator translates this into the OpenLineage HTTP transport's `api_key` (bearer) authentication.
117+
Combine it with the `tls` block above when the backend also needs TLS server verification.
118+
119+
[NOTE]
120+
====
121+
When `authenticationClassRef` is set, the operator delivers the *entire* transport configuration
122+
(type, URL and auth) to the driver through `OPENLINEAGE__*` environment variables rather than
123+
`spark.openlineage.transport.*` `--conf` properties.
124+
This is required: OpenLineage resolves the `transport` from a single source, so a transport defined
125+
via `sparkConf` would discard the environment-provided authentication.
126+
Consequently, do **not** override `spark.openlineage.transport.*` via `sparkConf` when using
127+
`authenticationClassRef` — doing so drops the credentials and the backend will reject the events.
128+
====
129+
71130
[#job-name]
72131
== Job name
73132

extra/crds.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1987,6 +1987,15 @@ spec:
19871987
OpenLineage connection definition as a resource.
19881988
Learn more about [OpenLineage](https://openlineage.io/).
19891989
properties:
1990+
authenticationClassRef:
1991+
description: |-
1992+
Name of an [`AuthenticationClass`](https://docs.stackable.tech/home/nightly/concepts/authentication) used
1993+
to authenticate against the OpenLineage backend. The `AuthenticationClass` is cluster-scoped
1994+
and referenced by name; it is resolved at runtime via
1995+
[`OpenLineageConnectionSpec::resolve_authentication_class`]. If not specified, no
1996+
authentication is used.
1997+
nullable: true
1998+
type: string
19901999
host:
19912000
description: 'Host of the OpenLineage backend without any protocol or port. For example: `marquez`.'
19922001
type: string
@@ -6693,6 +6702,15 @@ spec:
66936702
OpenLineage connection definition as a resource.
66946703
Learn more about [OpenLineage](https://openlineage.io/).
66956704
properties:
6705+
authenticationClassRef:
6706+
description: |-
6707+
Name of an [`AuthenticationClass`](https://docs.stackable.tech/home/nightly/concepts/authentication) used
6708+
to authenticate against the OpenLineage backend. The `AuthenticationClass` is cluster-scoped
6709+
and referenced by name; it is resolved at runtime via
6710+
[`OpenLineageConnectionSpec::resolve_authentication_class`]. If not specified, no
6711+
authentication is used.
6712+
nullable: true
6713+
type: string
66966714
host:
66976715
description: 'Host of the OpenLineage backend without any protocol or port. For example: `marquez`.'
66986716
type: string

rust/operator-binary/src/crd/constants.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,37 @@ pub const OPENLINEAGE_JAR_LOCAL_URI: &str =
126126
/// Appended to both driver and executor `extraJavaOptions`.
127127
pub const OPENLINEAGE_ADD_OPENS: &str = "--add-opens java.base/java.security=ALL-UNNAMED";
128128

129+
/// Env vars delivering the OpenLineage HTTP transport config via the OpenLineage Java client's
130+
/// `OPENLINEAGE__` env-var configuration (`__` separates the config hierarchy).
131+
///
132+
/// When an `AuthenticationClass` is configured, the operator delivers the **whole** transport this
133+
/// way rather than via `spark.openlineage.transport.*` `--conf`. This is required, not cosmetic:
134+
/// OpenLineage resolves `transport` from a single source, so a `--conf`-defined transport would
135+
/// drop the env-provided `auth` sub-tree entirely (verified against openlineage-spark 1.51.0).
136+
/// Delivering the token as a `secretKeyRef` env var also keeps it out of the spark-submit args.
137+
pub const OPENLINEAGE_TRANSPORT_TYPE_ENV: &str = "OPENLINEAGE__TRANSPORT__TYPE";
138+
139+
/// Env var carrying the OpenLineage HTTP transport URL. See [`OPENLINEAGE_TRANSPORT_TYPE_ENV`].
140+
pub const OPENLINEAGE_TRANSPORT_URL_ENV: &str = "OPENLINEAGE__TRANSPORT__URL";
141+
142+
/// The OpenLineage transport type the operator uses (the HTTP transport).
143+
pub const OPENLINEAGE_TRANSPORT_TYPE_HTTP: &str = "http";
144+
145+
/// Env var selecting the OpenLineage HTTP transport auth type. See [`OPENLINEAGE_TRANSPORT_TYPE_ENV`].
146+
pub const OPENLINEAGE_AUTH_TYPE_ENV: &str = "OPENLINEAGE__TRANSPORT__AUTH__TYPE";
147+
148+
/// Env var carrying the OpenLineage HTTP transport bearer token. Sourced from the referenced
149+
/// Secret via `secretKeyRef` (key [`OPENLINEAGE_AUTH_SECRET_KEY`]), so the operator never reads
150+
/// the token and it stays out of the Job/pod spec.
151+
pub const OPENLINEAGE_AUTH_API_KEY_ENV: &str = "OPENLINEAGE__TRANSPORT__AUTH__API_KEY";
152+
153+
/// The only OpenLineage HTTP transport auth type the operator supports: a static bearer token.
154+
pub const OPENLINEAGE_AUTH_TYPE_API_KEY: &str = "api_key";
155+
156+
/// Fixed key that must hold the bearer token inside the Secret referenced by the Static
157+
/// `AuthenticationClass`.
158+
pub const OPENLINEAGE_AUTH_SECRET_KEY: &str = "apiKey";
159+
129160
/// The JVM `security.properties` entries the operator sets by default (DNS cache TTLs).
130161
pub fn default_jvm_security_properties() -> BTreeMap<String, String> {
131162
[

0 commit comments

Comments
 (0)