Skip to content

Commit 429573a

Browse files
committed
docs: document environment variables resolver
Signed-off-by: Abhinav Gyawali <22275402+abhizer@users.noreply.github.com> [ci] apply automatic fixes Signed-off-by: feldera-bot <feldera-bot@feldera.com> apply suggestions from code review Signed-off-by: Abhinav Gyawali <22275402+abhizer@users.noreply.github.com>
1 parent e4e3467 commit 429573a

File tree

2 files changed

+109
-62
lines changed

2 files changed

+109
-62
lines changed

crates/feldera-types/src/secret_ref.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,7 @@ pub enum MaybeSecretRefParseError {
177177
name: String,
178178
e: EnvVarNameParseError,
179179
},
180-
#[error(
181-
"environment variable reference '{env_ref_str}' is not valid: name cannot be empty"
182-
)]
180+
#[error("environment variable reference '{env_ref_str}' is not valid: name cannot be empty")]
183181
EmptyEnvVarName { env_ref_str: String },
184182
}
185183

@@ -209,6 +207,7 @@ impl MaybeSecretRef {
209207
///
210208
/// Note that here is not checked whether the reference can actually be resolved.
211209
pub fn new(value: String) -> Result<MaybeSecretRef, MaybeSecretRefParseError> {
210+
let env_prefix = "${env:";
212211
if value.starts_with("${secret:") && value.ends_with('}') {
213212
// Because the pattern only has ASCII characters, they are encoded as single bytes.
214213
// The secret reference is extracted by slicing away the first 9 bytes and the last byte.
@@ -245,16 +244,15 @@ impl MaybeSecretRef {
245244
secret_ref_str: value,
246245
})
247246
}
248-
} else if value.starts_with("${env:") && value.ends_with('}') {
247+
} else if value.starts_with(env_prefix) && value.ends_with('}') {
249248
// Environment variable reference: `${env:<name>}`
250249
// The content is extracted by slicing away the first 6 bytes ("${env:") and the last byte ("}").
251-
let from_idx_incl = 6;
252-
let till_idx_excl = value.len() - 1;
253-
let name = value[from_idx_incl..till_idx_excl].to_string();
250+
let name = value
251+
.trim_start_matches(env_prefix)
252+
.trim_end_matches("}")
253+
.to_string();
254254
if name.is_empty() {
255-
Err(MaybeSecretRefParseError::EmptyEnvVarName {
256-
env_ref_str: value,
257-
})
255+
Err(MaybeSecretRefParseError::EmptyEnvVarName { env_ref_str: value })
258256
} else if let Err(e) = validate_env_var_name(&name) {
259257
Err(MaybeSecretRefParseError::InvalidEnvVarName {
260258
env_ref_str: value,

docs.feldera.com/docs/connectors/secret-references.md

Lines changed: 101 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,28 @@ Rather than directly supplying a secret (e.g., passwords, PEM, etc.) in the conn
44
configuration as a string, it is possible to refer to (externalize) them. This mechanism
55
in Feldera is called a **secret reference**.
66

7-
A secret reference is a string in the connector configuration JSON which takes a specific format:
7+
Feldera supports two types of references in connector configuration strings:
88

9-
```
10-
${secret:<provider>:<identifier>}
11-
```
9+
- **Secret references** — resolved from an external secret provider (e.g., Kubernetes):
10+
```
11+
${secret:<provider>:<identifier>}
12+
```
1213
1314
It refers to an identifiable secret provided by a provider. Feldera's control plane mounts the secret
1415
into the pipeline. When the pipeline initializes, it will replace the secret references in the
1516
configuration with their values. We currently only support a single secret provider, Kubernetes.
1617
17-
Feldera resolves secrets when a pipeline starts, as well as each time
18-
it resumes. Feldera does not write resolved values of secrets to
19-
checkpoints or journals.
18+
- **Environment variable references** — resolved from the pipeline process environment:
19+
```
20+
${env:<name>}
21+
```
22+
23+
When the pipeline initializes, it replaces all references in the connector configuration
24+
with their resolved values. Feldera resolves references when a pipeline starts, as well as
25+
each time it resumes. Feldera does not write resolved values to checkpoints or journals.
26+
27+
Use environment variables for non-sensitive deployment configuration only.
28+
Storing secrets in environment variables is generally discouraged; use a dedicated secret manager or secret store instead.
2029
2130
## Kubernetes
2231
@@ -80,7 +89,47 @@ We can then specify a connector configuration that refers to it using `${secret:
8089
}
8190
```
8291
83-
## Restrictions
92+
## Environment variables
93+
94+
### Usage
95+
96+
```
97+
${env:<name>}
98+
```
99+
100+
Here, `<name>` is the name of an environment variable following POSIX naming
101+
rules (letters, digits, and underscores, must start with a letter or underscore).
102+
103+
The reference is resolved at pipeline startup by reading the named variable from the pipeline
104+
process environment. This is useful for injecting configuration values (e.g., hostnames,
105+
credentials) via environment variables set in the `env` field of
106+
[`RuntimeConfig`](/api/patch-pipeline#body-runtime_config) or through the deployment environment.
107+
108+
### Example
109+
110+
```json
111+
{
112+
"transport": {
113+
"name": "kafka_input",
114+
"config": {
115+
"bootstrap.servers": "${env:KAFKA_BOOTSTRAP_SERVERS}",
116+
"sasl.password": "${env:KAFKA_SASL_PASSWORD}"
117+
}
118+
},
119+
"format": ...
120+
}
121+
```
122+
123+
### Restrictions
124+
125+
- The environment variable name must follow POSIX rules: only letters (`a``z`, `A``Z`),
126+
digits (`0``9`), and underscores (`_`), and must start with a letter or underscore
127+
- If the referenced environment variable is not set when the pipeline starts, the pipeline
128+
will fail to initialize with an error
129+
- It is not possible to have string values starting with `${env:` and ending with `}`
130+
without them being identified as an environment variable reference
131+
132+
## Restrictions (secret references)
84133

85134
- The secret name may only contain lowercase alphanumeric characters or hyphens, must start and end
86135
with a lowercase alphanumeric character and can be at most 63 characters long
@@ -89,51 +138,51 @@ We can then specify a connector configuration that refers to it using `${secret:
89138
- It is not possible to have any plain string value which starts with `${secret:` and ends with `}`
90139
without it being identified to be a secret reference.
91140
- Only string values in the connector configuration JSON under `transport.config` and `format.config`
92-
can be identified to be secret references (this excludes keys), for example (secret named `a` at
93-
data key `b` has value `value`):
94-
```
95-
{
96-
"transport": {
97-
"name": "some_transport",
98-
"config": {
99-
"${secret:kubernetes:a/b}": "${secret:kubernetes:a/b}",
100-
"v1": "${secret:kubernetes:a/b}",
101-
"v2": [ "${secret:kubernetes:a/b}" ]
102-
}
103-
},
104-
"format": {
105-
"name": "some_format",
106-
"config": {
107-
"v3": "${secret:kubernetes:a/b}"
108-
}
109-
},
110-
"index": "${secret:kubernetes:a/b}"
111-
}
112-
```
113-
... will be resolved to:
114-
```
115-
{
116-
"transport": {
117-
"name": "some_transport",
118-
"config": {
119-
"${secret:kubernetes:a/b}": "value",
120-
"v1": "value",
121-
"v2": [ "value" ]
122-
}
123-
},
124-
"format": {
125-
"name": "some_format",
126-
"config": {
127-
"v3": "value"
128-
}
129-
},
130-
"index": "${secret:kubernetes:a/b}"
131-
}
132-
```
141+
can be identified to be secret or environment variable references (this excludes keys), for example
142+
(secret named `a` at data key `b` has value `value`):
143+
```
144+
{
145+
"transport": {
146+
"name": "some_transport",
147+
"config": {
148+
"${secret:kubernetes:a/b}": "${secret:kubernetes:a/b}",
149+
"v1": "${secret:kubernetes:a/b}",
150+
"v2": [ "${secret:kubernetes:a/b}" ]
151+
}
152+
},
153+
"format": {
154+
"name": "some_format",
155+
"config": {
156+
"v3": "${secret:kubernetes:a/b}"
157+
}
158+
},
159+
"index": "${secret:kubernetes:a/b}"
160+
}
161+
```
162+
... will be resolved to:
163+
```
164+
{
165+
"transport": {
166+
"name": "some_transport",
167+
"config": {
168+
"${secret:kubernetes:a/b}": "value",
169+
"v1": "value",
170+
"v2": [ "value" ]
171+
}
172+
},
173+
"format": {
174+
"name": "some_format",
175+
"config": {
176+
"v3": "value"
177+
}
178+
},
179+
"index": "${secret:kubernetes:a/b}"
180+
}
181+
```
133182
- Because connector configuration is validated during SQL compilation without secret
134183
resolution, string values that require certain format for the connector configuration
135184
to be valid will not allow secret references (enumerations in particular, such as for
136185
the datagen connector `strategy` field)
137-
- It is not possible to specify a secret value type other than string
138-
- It is not possible to specify a secret as a substring, for example
139-
`abc${secret:kubernetes:a/b}def` does not work
186+
- It is not possible to specify a reference value type other than string
187+
- It is not possible to specify a reference as a substring, for example
188+
`abc${secret:kubernetes:a/b}def` and `abc${env:MY_VAR}def` do not work

0 commit comments

Comments
 (0)