-
-
Notifications
You must be signed in to change notification settings - Fork 7
feat: OPA Authorizer #777
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: OPA Authorizer #777
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
first batch of comments
@@ -168,7 +169,7 @@ stringData: | |||
|
|||
NiFi supports {nifi-docs-authorization}[multiple authorization methods], the available authorization methods depend on the chosen authentication method. | |||
|
|||
Authorization is not fully implemented by the Stackable Operator for Apache NiFi. | |||
The Stackable Operator for Apache NiFi supports a default authorization methods for each authentication method and authorization with Open Policy Agent. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont understand that sentence at all. Would you mind reformulating or explaining it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the idea is that there are different default authorization methods depending on the authentication method and OPA authorization which works with every authentication method.
configMapName: simple-opa <1> | ||
package: my-druid-rules <2> | ||
cache: | ||
entryTimeToLive: 5s <3> | ||
maxEntries: 10 <4> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
configMapName: simple-opa <1> | |
package: my-druid-rules <2> | |
cache: | |
entryTimeToLive: 5s <3> | |
maxEntries: 10 <4> | |
configMapName: simple-opa # <1> | |
package: my-nifi-rules # <2> | |
cache: | |
entryTimeToLive: 5s # <3> | |
maxEntries: 10 # <4> |
{ | ||
"action": { | ||
"name": <String> <1> | ||
}, | ||
"properties": { | ||
"isAccessAttempt": <String>, <2> | ||
"isAnonymous": <String> <3> | ||
}, | ||
"resource": { <4> | ||
"id": <String>, | ||
"name": <String>, | ||
"safeDescription": <String> | ||
}, | ||
"requestedResource": { <5> | ||
"id": <String>, | ||
"name": <String>, | ||
"safeDescription": <String> | ||
}, | ||
"identity": { | ||
"name": <String>, <6> | ||
"groups": String, <7> | ||
}, | ||
"resourceContext": <Object>, <8> | ||
"userContext": <Object> <9> | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the footnotes do not render correcly
"userContext": <Object> <9> | ||
} | ||
---- | ||
<1> The action taken against the resource. Possible values: `"read"` or `"write"`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think ticking or quoting is enough?
<1> The action taken against the resource. Possible values: `"read"` or `"write"`. | |
<1> The action taken against the resource. Possible values: `read` or `write`. |
|
||
=== Defining rego rules | ||
|
||
For a general explanation of how rules are written, please refer to the {opa-rego-docs}[OPA documentation]. For more information on NiFi's access policies please refer to the {nifi-docs-access-policies}[NiFi documentation]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For a general explanation of how rules are written, please refer to the {opa-rego-docs}[OPA documentation]. For more information on NiFi's access policies please refer to the {nifi-docs-access-policies}[NiFi documentation]. | |
For a general explanation of how rules are written, please refer to the {opa-rego-docs}[OPA documentation]. For more information on NiFi's access policies please refer to the {nifi-docs-access-policies}[NiFi documentation]. |
|
||
For a general explanation of how rules are written, please refer to the {opa-rego-docs}[OPA documentation]. For more information on NiFi's access policies please refer to the {nifi-docs-access-policies}[NiFi documentation]. | ||
|
||
Inside of your rego rules you have access to the content of the authorization request from NiFi as input for OPA: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inside of your rego rules you have access to the content of the authorization request from NiFi as input for OPA: | |
The payload sent by NiFi with each request to OPA, that is accessible within the rego rules, has the following structure: |
maxEntries: 10 <4> | ||
---- | ||
<1> The name of your OPA Stacklet (`simple-opa` in this case) | ||
<2> The RegoRule package to use for policy decisions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would go for "rego rule" instead of "RegoRule" as in other cases.
<3> Whether the entity accessing the resource is anonymous. Possible values: `"true"` or `"false"`. | ||
<4> The current resource being authorized on. | ||
<5> The original resource being requested. In cases with inherited policies, this will be an ancestor resource of the current resource. For the initial request, and cases without inheritance, the requested resource will be the same as the current resource. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this whole section is probably best displayed as table. Something like:
payload - description - possible values
action.name - The action taken against the resource - read/write
rust/operator-binary/src/crd/mod.rs
Outdated
/// Read more about authentication in the [security documentation](DOCS_BASE_URL_PLACEHOLDER/nifi/usage_guide/security#_authentication). | ||
// We don't add `#[serde(default)]` here, as we require authentication | ||
pub authentication: Vec<ClientAuthenticationDetails>, | ||
|
||
/// Authorization options. | ||
/// Learn more in the [NiFi authorization usage guide](DOCS_BASE_URL_PLACEHOLDER/nifi/usage-guide/security#authorization). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It fixes "security#_authentication", shouldnt it be "security#_authorization" as well (or the other way round)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should already prepare a more extensive test environment.
Meaning having a couple of users in keycloak with different access in the regos that can be tested via API and easily extended?
authorization: | ||
opa: | ||
configMapName: simple-opa <1> | ||
package: my-druid-rules <2> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
package: my-druid-rules <2> | |
package: my-nifi-rules <2> |
<1> The name of your OPA Stacklet (`simple-opa` in this case) | ||
<2> The RegoRule package to use for policy decisions. | ||
The package needs to contain an `allow` rule. | ||
This is optional and defaults to the name of the Druid Stacklet. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is optional and defaults to the name of the Druid Stacklet. | |
This is optional and defaults to the name of the NiFi Stacklet. |
rust/operator-binary/src/main.rs
Outdated
|| match nifi.spec.cluster_config.authorization.to_owned() { | ||
Some(trino_authorization) => match trino_authorization.opa { | ||
Some(opa_config) => opa_config.opa.config_map_name == config_map.name_any(), | ||
None => false, | ||
}, | ||
None => false, | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we split this to make it more readable?
fn references_config_map(
nifi: &DeserializeGuard<v1alpha1::NifiCluster>,
config_map: &DeserializeGuard<ConfigMap>,
) -> bool {
let Ok(nifi) = &nifi.0 else {
return false;
};
let references_zookeeper_config_map =
nifi.spec.cluster_config.zookeeper_config_map_name == config_map.name_any();
let references_authorization_config_map = references_authorization_config_map(nifi, config_map);
references_zookeeper_config_map || references_authorization_config_map
}
fn references_authorization_config_map(
nifi: &v1alpha1::NifiCluster,
config_map: &DeserializeGuard<ConfigMap>,
) -> bool {
nifi.spec
.cluster_config
.authorization
.as_ref()
.and_then(|authz| authz.opa.as_ref())
.map(|opa_config| opa_config.opa.config_map_name == config_map.name_any())
.unwrap_or(false)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did this in 13e60bc
Description
Adds support for authorization with OPA using Nifi OPA Plugin .
Should not be merged before: stackabletech/docker-images#1058
Definition of Done Checklist