diff --git a/core/src/main/java/org/jboss/intersmash/IntersmashConfig.java b/core/src/main/java/org/jboss/intersmash/IntersmashConfig.java index 1ed42ac85..62d0fe4b5 100644 --- a/core/src/main/java/org/jboss/intersmash/IntersmashConfig.java +++ b/core/src/main/java/org/jboss/intersmash/IntersmashConfig.java @@ -80,6 +80,12 @@ public class IntersmashConfig { private static final String HYPERFOIL_OPERATOR_PACKAGE_MANIFEST = "intersmash.hyperfoil.operators.package_manifest"; private static final String COMMUNITY_HYPERFOIL_OPERATOR_PACKAGE_MANIFEST = "hyperfoil-bundle"; private static final String DEFAULT_HYPERFOIL_OPERATOR_PACKAGE_MANIFEST = COMMUNITY_HYPERFOIL_OPERATOR_PACKAGE_MANIFEST; + private static final String AUTHORINO_OPERATOR_CATALOG_SOURCE_NAME = "intersmash.authorino.operators.catalog_source"; + private static final String AUTHORINO_OPERATOR_INDEX_IMAGE = "intersmash.authorino.operators.index_image"; + private static final String AUTHORINO_OPERATOR_CHANNEL = "intersmash.authorino.operators.channel"; + private static final String AUTHORINO_OPERATOR_PACKAGE_MANIFEST = "intersmash.authorino.operators.package_manifest"; + private static final String COMMUNITY_AUTHORINO_OPERATOR_PACKAGE_MANIFEST = "authorino-operator"; + private static final String DEFAULT_AUTHORINO_OPERATOR_PACKAGE_MANIFEST = COMMUNITY_AUTHORINO_OPERATOR_PACKAGE_MANIFEST; // Bootable Jar private static final String BOOTABLE_JAR_IMAGE_URL = "intersmash.bootable.jar.image"; @@ -228,6 +234,22 @@ public static String hyperfoilOperatorPackageManifest() { return XTFConfig.get(HYPERFOIL_OPERATOR_PACKAGE_MANIFEST, DEFAULT_HYPERFOIL_OPERATOR_PACKAGE_MANIFEST); } + public static String authorinoOperatorCatalogSource() { + return XTFConfig.get(AUTHORINO_OPERATOR_CATALOG_SOURCE_NAME, DEFAULT_OPERATOR_CATALOG_SOURCE_NAME); + } + + public static String authorinoOperatorIndexImage() { + return XTFConfig.get(AUTHORINO_OPERATOR_INDEX_IMAGE); + } + + public static String authorinoOperatorChannel() { + return XTFConfig.get(AUTHORINO_OPERATOR_CHANNEL); + } + + public static String authorinoOperatorPackageManifest() { + return XTFConfig.get(AUTHORINO_OPERATOR_PACKAGE_MANIFEST, DEFAULT_AUTHORINO_OPERATOR_PACKAGE_MANIFEST); + } + public static String bootableJarImageURL() { return XTFConfig.get(BOOTABLE_JAR_IMAGE_URL); } diff --git a/docs/Provisioner-by-Product.md b/docs/Provisioner-by-Product.md index a86704c94..df6efa38a 100644 --- a/docs/Provisioner-by-Product.md +++ b/docs/Provisioner-by-Product.md @@ -19,6 +19,7 @@ The provisioner is selected by a factory, based on the _Application class_ type | **Keycloak & Red Hat Build of Keycloak Operator** (see KeycloakOperatorApplication) | KeycloakOperatorProvisioner | :heavy_check_mark: | :heavy_check_mark: | | **Red Hat SSO Operator** (see RhSsoOperatorApplication) - **DEPRECATED** | RhSsoOperatorProvisioner | :x: | :heavy_check_mark: | | **WildFly & JBoss EAP 8 Operator** (see WildflyOperatorApplication) | WildflyOperatorProvisioner | :heavy_check_mark: | :heavy_check_mark: | +| **Authorino Operator** (see AuthorinoOperatorApplication) | AuthorinoOperatorProvisioner | :heavy_check_mark: | :heavy_check_mark: | | **Template based services** | | || | **JBoss EAP 7 Legacy s2i Build Template** (see Eap7LegacyS2iBuildTemplateApplication) | Eap7LegacyS2iBuildTemplateProvisioner | :x: | :heavy_check_mark: | | **JBoss EAP 7 Legacy s2i Deployment Template** (see Eap7TemplateOpenShiftApplication) | Eap7TemplateOpenShiftProvisioner | :x: | :heavy_check_mark: | diff --git a/provisioners/src/main/java/org/jboss/intersmash/application/openshift/AuthorinoOperatorApplication.java b/provisioners/src/main/java/org/jboss/intersmash/application/openshift/AuthorinoOperatorApplication.java new file mode 100644 index 000000000..5e4845d58 --- /dev/null +++ b/provisioners/src/main/java/org/jboss/intersmash/application/openshift/AuthorinoOperatorApplication.java @@ -0,0 +1,36 @@ +/** + * Copyright (C) 2023 Red Hat, Inc. + * + * Licensed 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. + */ +package org.jboss.intersmash.application.openshift; + +import java.util.List; + +import io.kuadrant.authorino.operator.v1beta1.Authorino; +import io.kuadrant.authorino.v1beta2.AuthConfig; + +/** + * End user Application interface which presents the Authorino operator service on OpenShift Container Platform. + * + * The application will be deployed by: + * + */ +public interface AuthorinoOperatorApplication extends OperatorApplication { + + Authorino getAuthorino(); + + List getAuthConfigs(); +} diff --git a/provisioners/src/main/java/org/jboss/intersmash/provision/openshift/AuthorinoOperatorProvisioner.java b/provisioners/src/main/java/org/jboss/intersmash/provision/openshift/AuthorinoOperatorProvisioner.java new file mode 100644 index 000000000..96b316b73 --- /dev/null +++ b/provisioners/src/main/java/org/jboss/intersmash/provision/openshift/AuthorinoOperatorProvisioner.java @@ -0,0 +1,228 @@ +/** + * Copyright (C) 2023 Red Hat, Inc. + * + * Licensed 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. + */ +package org.jboss.intersmash.provision.openshift; + +import java.util.List; +import java.util.stream.Collectors; + +import org.jboss.intersmash.IntersmashConfig; +import org.jboss.intersmash.application.openshift.AuthorinoOperatorApplication; +import org.jboss.intersmash.provision.openshift.operator.OperatorProvisioner; +import org.jboss.intersmash.provision.openshift.operator.authorino.AuthConfigList; +import org.jboss.intersmash.provision.openshift.operator.authorino.AuthorinoList; +import org.slf4j.event.Level; + +import cz.xtf.core.config.OpenShiftConfig; +import cz.xtf.core.event.helpers.EventHelper; +import cz.xtf.core.openshift.OpenShiftWaiters; +import cz.xtf.core.openshift.OpenShifts; +import cz.xtf.core.waiting.SimpleWaiter; +import io.fabric8.kubernetes.api.model.DeletionPropagation; +import io.fabric8.kubernetes.api.model.Pod; +import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition; +import io.fabric8.kubernetes.client.dsl.MixedOperation; +import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation; +import io.fabric8.kubernetes.client.dsl.Resource; +import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext; +import io.kuadrant.authorino.operator.v1beta1.Authorino; +import io.kuadrant.authorino.v1beta2.AuthConfig; +import lombok.NonNull; + +/** + * Authorino Operator based provisioner + * + * See:
+ * - https://github.com/Kuadrant/authorino/blob/main/docs/architecture.md
+ * - https://github.com/Kuadrant/authorino-operator + */ +public class AuthorinoOperatorProvisioner extends OperatorProvisioner { + private final static String AUTHORINO_RESOURCE = "authorinos.operator.authorino.kuadrant.io"; + private static NonNamespaceOperation> AUTHORINOS_CLIENT; + + private final static String AUTHCONFIG_RESOURCE = "authconfigs.authorino.kuadrant.io"; + private static NonNamespaceOperation> AUTHCONFIGS_CLIENT; + + private static final String OPERATOR_ID = IntersmashConfig.authorinoOperatorPackageManifest(); + + public AuthorinoOperatorProvisioner(@NonNull AuthorinoOperatorApplication application) { + super(application, OPERATOR_ID); + } + + public static String getOperatorId() { + return OPERATOR_ID; + } + + /** + * Get a client capable of working with {@link #AUTHORINO_RESOURCE} custom resource. + * + * @return client for operations with {@link #AUTHORINO_RESOURCE} custom resource + */ + public NonNamespaceOperation> authorinosClient() { + if (AUTHORINOS_CLIENT == null) { + CustomResourceDefinition crd = OpenShifts.admin().apiextensions().v1().customResourceDefinitions() + .withName(AUTHORINO_RESOURCE).get(); + CustomResourceDefinitionContext crdc = CustomResourceDefinitionContext.fromCrd(crd); + if (!getCustomResourceDefinitions().contains(AUTHORINO_RESOURCE)) { + throw new RuntimeException(String.format("[%s] custom resource is not provided by [%s] operator.", + AUTHORINO_RESOURCE, OPERATOR_ID)); + } + MixedOperation> client = OpenShifts + .master().newHasMetadataOperation(crdc, Authorino.class, AuthorinoList.class); + AUTHORINOS_CLIENT = client.inNamespace(OpenShiftConfig.namespace()); + } + return AUTHORINOS_CLIENT; + } + + /** + * Get a reference to an {@link Authorino} custom resource. Use get() to get the actual object, or null in case it does not + * exist on tested cluster. + * + * @return A concrete {@link Resource} instance representing the {@link Authorino} resource definition + */ + public Resource authorino() { + return authorinosClient().withName(getApplication().getAuthorino().getMetadata().getName()); + } + + /** + * Get a client capable of working with {@link #AUTHCONFIG_RESOURCE} custom resource. + * + * @return client for operations with {@link #AUTHCONFIG_RESOURCE} custom resource + */ + public NonNamespaceOperation> authConfigsClient() { + if (AUTHCONFIGS_CLIENT == null) { + CustomResourceDefinition crd = OpenShifts.admin().apiextensions().v1().customResourceDefinitions() + .withName(AUTHCONFIG_RESOURCE).get(); + CustomResourceDefinitionContext crdc = CustomResourceDefinitionContext.fromCrd(crd); + if (!getCustomResourceDefinitions().contains(AUTHCONFIG_RESOURCE)) { + throw new RuntimeException(String.format("[%s] custom resource is not provided by [%s] operator.", + AUTHCONFIG_RESOURCE, OPERATOR_ID)); + } + MixedOperation> amqClient = OpenShifts + .master().newHasMetadataOperation(crdc, AuthConfig.class, AuthConfigList.class); + AUTHCONFIGS_CLIENT = amqClient.inNamespace(OpenShiftConfig.namespace()); + } + return AUTHCONFIGS_CLIENT; + } + + /** + * Get all {@link AuthConfig} custom resource instances maintained by the current operator instance. + * + * Be aware that this method return just a references to the CRs, they might not actually exist on the cluster. + * Use get() to get the actual object, or null in case it does not exist on tested cluster. + * @return A list of {@link Resource} instances representing the {@link AuthConfig} resource definitions + */ + public List> authConfigs() { + AuthorinoOperatorApplication application = getApplication(); + return application.getAuthConfigs().stream() + .map(a -> a.getMetadata().getName()) + .map(this::authConfig) + .collect(Collectors.toList()); + } + + /** + * Get a reference to a {@link AuthConfig} custom resource object. + * Use get() to get the actual object, or null in case it does not exist on tested cluster. + * + * @param name name of the {@link AuthConfig} custom resource + * @return A concrete {@link Resource} instance representing the {@link AuthConfig} resource definition + */ + public Resource authConfig(final String name) { + return authConfigsClient().withName(name); + } + + @Override + public void deploy() { + ffCheck = FailFastUtils.getFailFastCheck(EventHelper.timeOfLastEventBMOrTestNamespaceOrEpoch(), + getApplication().getName()); + subscribe(); + final int replicas = getApplication().getAuthorino().getSpec().getReplicas(); + // deploy the authorino CR + authorinosClient().createOrReplace(getApplication().getAuthorino()); + // deploy AuthConfig CR(s) + getApplication().getAuthConfigs().stream() + .forEach(authConfig -> authConfigsClient().createOrReplace(authConfig)); + // wait for authorino instance to be created... + new SimpleWaiter(() -> authorino().get() != null) + .failFast(ffCheck) + .level(Level.DEBUG) + .waitFor(); + // and then ready + OpenShiftWaiters.get(OpenShiftProvisioner.openShift, ffCheck).areExactlyNPodsReady(replicas, + authorino().get().getKind(), getApplication().getAuthorino().getMetadata().getName()) + .level(Level.DEBUG) + .waitFor(); + // wait for AuthConfig CR(s) to be created + authConfigs() + .forEach(authConfig -> new SimpleWaiter(() -> authConfig.get() != null).level(Level.DEBUG).waitFor()); + } + + @Override + public void undeploy() { + // delete the AuthConfig CR(s) + authConfigs().forEach(authConfig -> authConfig.withPropagationPolicy(DeletionPropagation.FOREGROUND).delete()); + // delete the Authorino CR, first scaling it down to 0 (graceful shutdown) + this.scale(0, Boolean.TRUE); + authorino().withPropagationPolicy(DeletionPropagation.FOREGROUND).delete(); + // wait + new SimpleWaiter(() -> authorinosClient().list().getItems().size() == 0).failFast(ffCheck).level(Level.DEBUG) + .waitFor(); + authConfigs().forEach( + authConfig -> new SimpleWaiter(() -> authConfig.get() == null).level(Level.DEBUG).failFast(ffCheck).waitFor()); + // unsubscribe + unsubscribe(); + } + + @Override + public void scale(int replicas, boolean wait) { + Authorino authorino = authorino().get(); + authorino.getSpec().setReplicas(replicas); + authorino().replace(authorino); + if (wait) { + OpenShiftWaiters.get(OpenShiftProvisioner.openShift, ffCheck) + .areExactlyNPodsReady(replicas, authorino.getKind(), authorino.getMetadata().getName()) + .level(Level.DEBUG) + .waitFor(); + } + } + + /** + * Get the provisioned application service related Pods + *

+ * Currently blocked by the fact that Pod Status pod names do not reflect the reality + *

+ * + * @return A list of related {@link Pod} instances + */ + @Override + public List getPods() { + return OpenShiftProvisioner.openShift.getLabeledPods("authorino-resource", getApplication().getName()); + } + + @Override + protected String getOperatorCatalogSource() { + return IntersmashConfig.authorinoOperatorCatalogSource(); + } + + @Override + protected String getOperatorIndexImage() { + return IntersmashConfig.authorinoOperatorIndexImage(); + } + + @Override + protected String getOperatorChannel() { + return IntersmashConfig.authorinoOperatorChannel(); + } +} diff --git a/provisioners/src/main/java/org/jboss/intersmash/provision/openshift/AuthorinoOperatorProvisionerFactory.java b/provisioners/src/main/java/org/jboss/intersmash/provision/openshift/AuthorinoOperatorProvisionerFactory.java new file mode 100644 index 000000000..3e8f0fac7 --- /dev/null +++ b/provisioners/src/main/java/org/jboss/intersmash/provision/openshift/AuthorinoOperatorProvisionerFactory.java @@ -0,0 +1,33 @@ +/** + * Copyright (C) 2023 Red Hat, Inc. + * + * Licensed 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. + */ +package org.jboss.intersmash.provision.openshift; + +import org.jboss.intersmash.application.Application; +import org.jboss.intersmash.application.openshift.AuthorinoOperatorApplication; +import org.jboss.intersmash.provision.ProvisionerFactory; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class AuthorinoOperatorProvisionerFactory implements ProvisionerFactory { + + @Override + public AuthorinoOperatorProvisioner getProvisioner(Application application) { + if (AuthorinoOperatorApplication.class.isAssignableFrom(application.getClass())) + return new AuthorinoOperatorProvisioner((AuthorinoOperatorApplication) application); + return null; + } +} diff --git a/provisioners/src/main/java/org/jboss/intersmash/provision/openshift/operator/authorino/AuthConfigList.java b/provisioners/src/main/java/org/jboss/intersmash/provision/openshift/operator/authorino/AuthConfigList.java new file mode 100644 index 000000000..ebe5200aa --- /dev/null +++ b/provisioners/src/main/java/org/jboss/intersmash/provision/openshift/operator/authorino/AuthConfigList.java @@ -0,0 +1,22 @@ +/** + * Copyright (C) 2023 Red Hat, Inc. + * + * Licensed 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. + */ +package org.jboss.intersmash.provision.openshift.operator.authorino; + +import io.fabric8.kubernetes.client.CustomResourceList; +import io.kuadrant.authorino.v1beta2.AuthConfig; + +public class AuthConfigList extends CustomResourceList { +} diff --git a/provisioners/src/main/java/org/jboss/intersmash/provision/openshift/operator/authorino/AuthorinoList.java b/provisioners/src/main/java/org/jboss/intersmash/provision/openshift/operator/authorino/AuthorinoList.java new file mode 100644 index 000000000..a5ac766f9 --- /dev/null +++ b/provisioners/src/main/java/org/jboss/intersmash/provision/openshift/operator/authorino/AuthorinoList.java @@ -0,0 +1,22 @@ +/** + * Copyright (C) 2023 Red Hat, Inc. + * + * Licensed 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. + */ +package org.jboss.intersmash.provision.openshift.operator.authorino; + +import io.fabric8.kubernetes.client.CustomResourceList; +import io.kuadrant.authorino.operator.v1beta1.Authorino; + +public class AuthorinoList extends CustomResourceList { +} diff --git a/provisioners/src/main/resources/META-INF/services/org.jboss.intersmash.provision.ProvisionerFactory b/provisioners/src/main/resources/META-INF/services/org.jboss.intersmash.provision.ProvisionerFactory index 5510c7640..b74f71949 100644 --- a/provisioners/src/main/resources/META-INF/services/org.jboss.intersmash.provision.ProvisionerFactory +++ b/provisioners/src/main/resources/META-INF/services/org.jboss.intersmash.provision.ProvisionerFactory @@ -15,4 +15,5 @@ org.jboss.intersmash.provision.openshift.Eap7ImageOpenShiftProvisionerFactory org.jboss.intersmash.provision.openshift.Eap7LegacyS2iBuildTemplateProvisionerFactory org.jboss.intersmash.provision.openshift.Eap7TemplateOpenShiftProvisionerFactory org.jboss.intersmash.provision.openshift.HyperfoilOperatorProvisionerFactory +org.jboss.intersmash.provision.openshift.AuthorinoOperatorProvisionerFactory diff --git a/provisioners/src/main/resources/crds/authorino.kuadrant.io_authconfigs.yaml b/provisioners/src/main/resources/crds/authorino.kuadrant.io_authconfigs.yaml new file mode 100644 index 000000000..800f877a4 --- /dev/null +++ b/provisioners/src/main/resources/crds/authorino.kuadrant.io_authconfigs.yaml @@ -0,0 +1,4918 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.0 + creationTimestamp: null + name: authconfigs.authorino.kuadrant.io +spec: + group: authorino.kuadrant.io + names: + kind: AuthConfig + listKind: AuthConfigList + plural: authconfigs + singular: authconfig + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Ready for all hosts + jsonPath: .status.summary.ready + name: Ready + type: string + - description: Number of hosts ready + jsonPath: .status.summary.numHostsReady + name: Hosts + type: string + - description: Number of trusted identity sources + jsonPath: .status.summary.numIdentitySources + name: Authentication + priority: 2 + type: integer + - description: Number of external metadata sources + jsonPath: .status.summary.numMetadataSources + name: Metadata + priority: 2 + type: integer + - description: Number of authorization policies + jsonPath: .status.summary.numAuthorizationPolicies + name: Authorization + priority: 2 + type: integer + - description: Number of items added to the authorization response + jsonPath: .status.summary.numResponseItems + name: Response + priority: 2 + type: integer + - description: Whether issuing Festival Wristbands + jsonPath: .status.summary.festivalWristbandEnabled + name: Wristband + priority: 2 + type: boolean + name: v1beta1 + schema: + openAPIV3Schema: + description: AuthConfig is the schema for Authorino's AuthConfig API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Specifies the desired state of the AuthConfig resource, i.e. + the authencation/authorization scheme to be applied to protect the matching + service hosts. + properties: + authorization: + description: Authorization is the list of authorization policies. + All policies in this list MUST evaluate to "true" for a request + be successful in the authorization phase. + items: + description: 'Authorization policy to be enforced. Apart from "name", + one of the following parameters is required and only one of the + following parameters is allowed: "opa", "json" or "kubernetes".' + properties: + authzed: + description: Authzed authorization + properties: + endpoint: + description: Endpoint of the Authzed service. + type: string + insecure: + description: Insecure HTTP connection (i.e. disables TLS + verification) + type: boolean + permission: + description: The name of the permission (or relation) on + which to execute the check. + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from the + authorization JSON. It can be any path pattern + to fetch from the authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers are + available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and @strip.' + type: string + type: object + type: object + resource: + description: The resource on which to check the permission + or relation. + properties: + kind: + description: StaticOrDynamicValue is either a constant + static string value or a config for fetching a value + from a dynamic source (e.g. a path pattern of authorization + JSON) + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from + the authorization JSON. It can be any path + pattern to fetch from the authorization JSON + (e.g. ''context.request.http.host'') or a + string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers + are available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and + @strip.' + type: string + type: object + type: object + name: + description: StaticOrDynamicValue is either a constant + static string value or a config for fetching a value + from a dynamic source (e.g. a path pattern of authorization + JSON) + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from + the authorization JSON. It can be any path + pattern to fetch from the authorization JSON + (e.g. ''context.request.http.host'') or a + string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers + are available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and + @strip.' + type: string + type: object + type: object + type: object + sharedSecretRef: + description: Reference to a Secret key whose value will + be used by Authorino to authenticate with the Authzed + service. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: The name of the secret in the Authorino's + namespace to select from. + type: string + required: + - key + - name + type: object + subject: + description: The subject that will be checked for the permission + or relation. + properties: + kind: + description: StaticOrDynamicValue is either a constant + static string value or a config for fetching a value + from a dynamic source (e.g. a path pattern of authorization + JSON) + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from + the authorization JSON. It can be any path + pattern to fetch from the authorization JSON + (e.g. ''context.request.http.host'') or a + string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers + are available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and + @strip.' + type: string + type: object + type: object + name: + description: StaticOrDynamicValue is either a constant + static string value or a config for fetching a value + from a dynamic source (e.g. a path pattern of authorization + JSON) + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from + the authorization JSON. It can be any path + pattern to fetch from the authorization JSON + (e.g. ''context.request.http.host'') or a + string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers + are available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and + @strip.' + type: string + type: object + type: object + type: object + required: + - endpoint + type: object + cache: + description: Caching options for the policy evaluation results + when enforcing this config. Omit it to avoid caching policy + evaluation results for this config. + properties: + key: + description: Key used to store the entry in the cache. Cache + entries from different metadata configs are stored and + managed separately regardless of the key. + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from the + authorization JSON. It can be any path pattern + to fetch from the authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers are + available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and @strip.' + type: string + type: object + type: object + ttl: + default: 60 + description: Duration (in seconds) of the external data + in the cache before pulled again from the source. + type: integer + required: + - key + type: object + json: + description: JSON pattern matching authorization policy. + properties: + rules: + description: The rules that must all evaluate to "true" + for the request to be authorized. + items: + properties: + all: + description: A list of pattern expressions to be evaluated + as a logical AND. + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + any: + description: A list of pattern expressions to be evaluated + as a logical OR. + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + operator: + description: 'The binary operator to be applied to + the content fetched from the authorization JSON, + for comparison with "value". Possible values are: + "eq" (equal to), "neq" (not equal to), "incl" (includes; + for arrays), "excl" (excludes; for arrays), "matches" + (regex)' + enum: + - eq + - neq + - incl + - excl + - matches + type: string + patternRef: + description: Name of a named pattern + type: string + selector: + description: Any pattern supported by https://pkg.go.dev/github.com/tidwall/gjson. + The value is used to fetch content from the input + authorization JSON built by Authorino along the + identity and metadata phases. + type: string + value: + description: The value of reference for the comparison + with the content fetched from the authorization + JSON. If used with the "matches" operator, the value + must compile to a valid Golang regex. + type: string + type: object + type: array + required: + - rules + type: object + kubernetes: + description: Kubernetes authorization policy based on `SubjectAccessReview` + Path and Verb are inferred from the request. + properties: + groups: + description: Groups to test for. + items: + type: string + type: array + resourceAttributes: + description: Use ResourceAttributes for checking permissions + on Kubernetes resources If omitted, it performs a non-resource + `SubjectAccessReview`, with verb and path inferred from + the request. + properties: + group: + description: StaticOrDynamicValue is either a constant + static string value or a config for fetching a value + from a dynamic source (e.g. a path pattern of authorization + JSON) + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from + the authorization JSON. It can be any path + pattern to fetch from the authorization JSON + (e.g. ''context.request.http.host'') or a + string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers + are available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and + @strip.' + type: string + type: object + type: object + name: + description: StaticOrDynamicValue is either a constant + static string value or a config for fetching a value + from a dynamic source (e.g. a path pattern of authorization + JSON) + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from + the authorization JSON. It can be any path + pattern to fetch from the authorization JSON + (e.g. ''context.request.http.host'') or a + string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers + are available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and + @strip.' + type: string + type: object + type: object + namespace: + description: StaticOrDynamicValue is either a constant + static string value or a config for fetching a value + from a dynamic source (e.g. a path pattern of authorization + JSON) + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from + the authorization JSON. It can be any path + pattern to fetch from the authorization JSON + (e.g. ''context.request.http.host'') or a + string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers + are available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and + @strip.' + type: string + type: object + type: object + resource: + description: StaticOrDynamicValue is either a constant + static string value or a config for fetching a value + from a dynamic source (e.g. a path pattern of authorization + JSON) + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from + the authorization JSON. It can be any path + pattern to fetch from the authorization JSON + (e.g. ''context.request.http.host'') or a + string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers + are available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and + @strip.' + type: string + type: object + type: object + subresource: + description: StaticOrDynamicValue is either a constant + static string value or a config for fetching a value + from a dynamic source (e.g. a path pattern of authorization + JSON) + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from + the authorization JSON. It can be any path + pattern to fetch from the authorization JSON + (e.g. ''context.request.http.host'') or a + string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers + are available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and + @strip.' + type: string + type: object + type: object + verb: + description: StaticOrDynamicValue is either a constant + static string value or a config for fetching a value + from a dynamic source (e.g. a path pattern of authorization + JSON) + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from + the authorization JSON. It can be any path + pattern to fetch from the authorization JSON + (e.g. ''context.request.http.host'') or a + string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers + are available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and + @strip.' + type: string + type: object + type: object + type: object + user: + description: User to test for. If without "Groups", then + is it interpreted as "What if User were not a member of + any groups" + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from the + authorization JSON. It can be any path pattern + to fetch from the authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers are + available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and @strip.' + type: string + type: object + type: object + required: + - user + type: object + metrics: + default: false + description: Whether this authorization config should generate + individual observability metrics + type: boolean + name: + description: Name of the authorization policy. It can be used + to refer to the resolved authorization object in other configs. + type: string + opa: + description: Open Policy Agent (OPA) authorization policy. + properties: + allValues: + default: false + description: Returns the value of all Rego rules in the + virtual document. Values can be read in subsequent evaluators/phases + of the Auth Pipeline. Otherwise, only the default `allow` + rule will be exposed. Returning all Rego rules can affect + performance of OPA policies during reconciliation (policy + precompile) and at runtime. + type: boolean + externalRegistry: + description: External registry of OPA policies. + properties: + credentials: + description: Defines where client credentials will be + passed in the request to the service. If omitted, + it defaults to client credentials passed in the HTTP + Authorization header and the "Bearer" prefix expected + prepended to the secret value. + properties: + in: + default: authorization_header + description: The location in the request where client + credentials shall be passed on requests authenticating + with this identity source/authentication mode. + enum: + - authorization_header + - custom_header + - query + - cookie + type: string + keySelector: + description: Used in conjunction with the `in` parameter. + When used with `authorization_header`, the value + is the prefix of the client credentials string, + separated by a white-space, in the HTTP Authorization + header (e.g. "Bearer", "Basic"). When used with + `custom_header`, `query` or `cookie`, the value + is the name of the HTTP header, query string parameter + or cookie key, respectively. + type: string + required: + - keySelector + type: object + endpoint: + description: Endpoint of the HTTP external registry. + The endpoint must respond with either plain/text or + application/json content-type. In the latter case, + the JSON returned in the body must include a path + `result.raw`, where the raw Rego policy will be extracted + from. This complies with the specification of the + OPA REST API (https://www.openpolicyagent.org/docs/latest/rest-api/#get-a-policy). + type: string + sharedSecretRef: + description: Reference to a Secret key whose value will + be passed by Authorino in the request. The HTTP service + can use the shared secret to authenticate the origin + of the request. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: The name of the secret in the Authorino's + namespace to select from. + type: string + required: + - key + - name + type: object + ttl: + description: Duration (in seconds) of the external data + in the cache before pulled again from the source. + type: integer + type: object + inlineRego: + description: Authorization policy as a Rego language document. + The Rego document must include the "allow" condition, + set by Authorino to "false" by default (i.e. requests + are unauthorized unless changed). The Rego document must + NOT include the "package" declaration in line 1. + type: string + type: object + priority: + default: 0 + description: Priority group of the config. All configs in the + same priority group are evaluated concurrently; consecutive + priority groups are evaluated sequentially. + type: integer + when: + description: Conditions for Authorino to enforce this authorization + policy. If omitted, the config will be enforced for all requests. + If present, all conditions must match for the config to be + enforced; otherwise, the config will be skipped. + items: + properties: + all: + description: A list of pattern expressions to be evaluated + as a logical AND. + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + any: + description: A list of pattern expressions to be evaluated + as a logical OR. + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + operator: + description: 'The binary operator to be applied to the + content fetched from the authorization JSON, for comparison + with "value". Possible values are: "eq" (equal to), + "neq" (not equal to), "incl" (includes; for arrays), + "excl" (excludes; for arrays), "matches" (regex)' + enum: + - eq + - neq + - incl + - excl + - matches + type: string + patternRef: + description: Name of a named pattern + type: string + selector: + description: Any pattern supported by https://pkg.go.dev/github.com/tidwall/gjson. + The value is used to fetch content from the input authorization + JSON built by Authorino along the identity and metadata + phases. + type: string + value: + description: The value of reference for the comparison + with the content fetched from the authorization JSON. + If used with the "matches" operator, the value must + compile to a valid Golang regex. + type: string + type: object + type: array + required: + - name + type: object + type: array + callbacks: + description: List of callback configs. Authorino sends callbacks to + specified endpoints at the end of the auth pipeline. + items: + description: Endpoints to callback at the end of each auth pipeline. + properties: + http: + description: Generic HTTP interface to obtain authorization + metadata from a HTTP service. + properties: + body: + description: Raw body of the HTTP request. Supersedes 'bodyParameters'; + use either one or the other. Use it with method=POST; + for GET requests, set parameters as query string in the + 'endpoint' (placeholders can be used). + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from the + authorization JSON. It can be any path pattern + to fetch from the authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers are + available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and @strip.' + type: string + type: object + type: object + bodyParameters: + description: Custom parameters to encode in the body of + the HTTP request. Superseded by 'body'; use either one + or the other. Use it with method=POST; for GET requests, + set parameters as query string in the 'endpoint' (placeholders + can be used). + items: + properties: + name: + description: The name of the JSON property + type: string + value: + description: Static value of the JSON property + x-kubernetes-preserve-unknown-fields: true + valueFrom: + description: Dynamic value of the JSON property + properties: + authJSON: + description: 'Selector to fetch a value from the + authorization JSON. It can be any path pattern + to fetch from the authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers + are available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and + @strip.' + type: string + type: object + required: + - name + type: object + type: array + contentType: + default: application/x-www-form-urlencoded + description: Content-Type of the request body. Shapes how + 'bodyParameters' are encoded. Use it with method=POST; + for GET requests, Content-Type is automatically set to + 'text/plain'. + enum: + - application/x-www-form-urlencoded + - application/json + type: string + credentials: + description: Defines where client credentials will be passed + in the request to the service. If omitted, it defaults + to client credentials passed in the HTTP Authorization + header and the "Bearer" prefix expected prepended to the + secret value. + properties: + in: + default: authorization_header + description: The location in the request where client + credentials shall be passed on requests authenticating + with this identity source/authentication mode. + enum: + - authorization_header + - custom_header + - query + - cookie + type: string + keySelector: + description: Used in conjunction with the `in` parameter. + When used with `authorization_header`, the value is + the prefix of the client credentials string, separated + by a white-space, in the HTTP Authorization header + (e.g. "Bearer", "Basic"). When used with `custom_header`, + `query` or `cookie`, the value is the name of the + HTTP header, query string parameter or cookie key, + respectively. + type: string + required: + - keySelector + type: object + endpoint: + description: Endpoint of the HTTP service. The endpoint + accepts variable placeholders in the format "{selector}", + where "selector" is any pattern supported by https://pkg.go.dev/github.com/tidwall/gjson + and selects value from the authorization JSON. E.g. https://ext-auth-server.io/metadata?p={context.request.http.path} + type: string + headers: + description: Custom headers in the HTTP request. + items: + properties: + name: + description: The name of the JSON property + type: string + value: + description: Static value of the JSON property + x-kubernetes-preserve-unknown-fields: true + valueFrom: + description: Dynamic value of the JSON property + properties: + authJSON: + description: 'Selector to fetch a value from the + authorization JSON. It can be any path pattern + to fetch from the authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers + are available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and + @strip.' + type: string + type: object + required: + - name + type: object + type: array + method: + default: GET + description: 'HTTP verb used in the request to the service. + Accepted values: GET (default), POST. When the request + method is POST, the authorization JSON is passed in the + body of the request.' + enum: + - GET + - POST + type: string + oauth2: + description: Authentication with the HTTP service by OAuth2 + Client Credentials grant. + properties: + cache: + default: true + description: Caches and reuses the token until expired. + Set it to false to force fetch the token at every + authorization request regardless of expiration. + type: boolean + clientId: + description: OAuth2 Client ID. + type: string + clientSecretRef: + description: Reference to a Kubernetes Secret key that + stores that OAuth2 Client Secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: The name of the secret in the Authorino's + namespace to select from. + type: string + required: + - key + - name + type: object + extraParams: + additionalProperties: + type: string + description: Optional extra parameters for the requests + to the token URL. + type: object + scopes: + description: Optional scopes for the client credentials + grant, if supported by he OAuth2 server. + items: + type: string + type: array + tokenUrl: + description: Token endpoint URL of the OAuth2 resource + server. + type: string + required: + - clientId + - clientSecretRef + - tokenUrl + type: object + sharedSecretRef: + description: Reference to a Secret key whose value will + be passed by Authorino in the request. The HTTP service + can use the shared secret to authenticate the origin of + the request. Ignored if used together with oauth2. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: The name of the secret in the Authorino's + namespace to select from. + type: string + required: + - key + - name + type: object + required: + - endpoint + type: object + metrics: + default: false + description: Whether this callback config should generate individual + observability metrics + type: boolean + name: + description: Name of the callback. It can be used to refer to + the resolved callback response in other configs. + type: string + priority: + default: 0 + description: Priority group of the config. All configs in the + same priority group are evaluated concurrently; consecutive + priority groups are evaluated sequentially. + type: integer + when: + description: Conditions for Authorino to perform this callback. + If omitted, the callback will be attempted for all requests. + If present, all conditions must match for the callback to + be attempted; otherwise, the callback will be skipped. + items: + properties: + all: + description: A list of pattern expressions to be evaluated + as a logical AND. + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + any: + description: A list of pattern expressions to be evaluated + as a logical OR. + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + operator: + description: 'The binary operator to be applied to the + content fetched from the authorization JSON, for comparison + with "value". Possible values are: "eq" (equal to), + "neq" (not equal to), "incl" (includes; for arrays), + "excl" (excludes; for arrays), "matches" (regex)' + enum: + - eq + - neq + - incl + - excl + - matches + type: string + patternRef: + description: Name of a named pattern + type: string + selector: + description: Any pattern supported by https://pkg.go.dev/github.com/tidwall/gjson. + The value is used to fetch content from the input authorization + JSON built by Authorino along the identity and metadata + phases. + type: string + value: + description: The value of reference for the comparison + with the content fetched from the authorization JSON. + If used with the "matches" operator, the value must + compile to a valid Golang regex. + type: string + type: object + type: array + required: + - http + - name + type: object + type: array + denyWith: + description: Custom denial response codes, statuses and headers to + override default 40x's. + properties: + unauthenticated: + description: Denial status customization when the request is unauthenticated. + properties: + body: + description: HTTP response body to override the default denial + body. + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from the authorization + JSON. It can be any path pattern to fetch from the + authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers are + available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and @strip.' + type: string + type: object + type: object + code: + description: HTTP status code to override the default denial + status code. + format: int64 + maximum: 599 + minimum: 300 + type: integer + headers: + description: HTTP response headers to override the default + denial headers. + items: + properties: + name: + description: The name of the JSON property + type: string + value: + description: Static value of the JSON property + x-kubernetes-preserve-unknown-fields: true + valueFrom: + description: Dynamic value of the JSON property + properties: + authJSON: + description: 'Selector to fetch a value from the + authorization JSON. It can be any path pattern + to fetch from the authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers are + available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and @strip.' + type: string + type: object + required: + - name + type: object + type: array + message: + description: HTTP message to override the default denial message. + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from the authorization + JSON. It can be any path pattern to fetch from the + authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers are + available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and @strip.' + type: string + type: object + type: object + type: object + unauthorized: + description: Denial status customization when the request is unauthorized. + properties: + body: + description: HTTP response body to override the default denial + body. + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from the authorization + JSON. It can be any path pattern to fetch from the + authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers are + available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and @strip.' + type: string + type: object + type: object + code: + description: HTTP status code to override the default denial + status code. + format: int64 + maximum: 599 + minimum: 300 + type: integer + headers: + description: HTTP response headers to override the default + denial headers. + items: + properties: + name: + description: The name of the JSON property + type: string + value: + description: Static value of the JSON property + x-kubernetes-preserve-unknown-fields: true + valueFrom: + description: Dynamic value of the JSON property + properties: + authJSON: + description: 'Selector to fetch a value from the + authorization JSON. It can be any path pattern + to fetch from the authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers are + available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and @strip.' + type: string + type: object + required: + - name + type: object + type: array + message: + description: HTTP message to override the default denial message. + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from the authorization + JSON. It can be any path pattern to fetch from the + authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers are + available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and @strip.' + type: string + type: object + type: object + type: object + type: object + hosts: + description: The list of public host names of the services protected + by this authentication/authorization scheme. Authorino uses the + requested host to lookup for the corresponding authentication/authorization + configs to enforce. + items: + type: string + type: array + identity: + description: List of identity sources/authentication modes. At least + one config of this list MUST evaluate to a valid identity for a + request to be successful in the identity verification phase. + items: + description: 'The identity source/authentication mode config. Apart + from "name", one of the following parameters is required and only + one of the following parameters is allowed: "oicd", "apiKey" or + "kubernetes".' + properties: + anonymous: + type: object + apiKey: + properties: + allNamespaces: + default: false + description: Whether Authorino should look for API key secrets + in all namespaces or only in the same namespace as the + AuthConfig. Enabling this option in namespaced Authorino + instances has no effect. + type: boolean + selector: + description: Label selector used by Authorino to match secrets + from the cluster storing valid credentials to authenticate + to this service + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, + NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists + or DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field + is "key", the operator is "In", and the values array + contains only "value". The requirements are ANDed. + type: object + type: object + required: + - selector + type: object + cache: + description: Caching options for the identity resolved when + applying this config. Omit it to avoid caching identity objects + for this config. + properties: + key: + description: Key used to store the entry in the cache. Cache + entries from different metadata configs are stored and + managed separately regardless of the key. + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from the + authorization JSON. It can be any path pattern + to fetch from the authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers are + available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and @strip.' + type: string + type: object + type: object + ttl: + default: 60 + description: Duration (in seconds) of the external data + in the cache before pulled again from the source. + type: integer + required: + - key + type: object + credentials: + description: Defines where client credentials are required to + be passed in the request for this identity source/authentication + mode. If omitted, it defaults to client credentials passed + in the HTTP Authorization header and the "Bearer" prefix expected + prepended to the credentials value (token, API key, etc). + properties: + in: + default: authorization_header + description: The location in the request where client credentials + shall be passed on requests authenticating with this identity + source/authentication mode. + enum: + - authorization_header + - custom_header + - query + - cookie + type: string + keySelector: + description: Used in conjunction with the `in` parameter. + When used with `authorization_header`, the value is the + prefix of the client credentials string, separated by + a white-space, in the HTTP Authorization header (e.g. + "Bearer", "Basic"). When used with `custom_header`, `query` + or `cookie`, the value is the name of the HTTP header, + query string parameter or cookie key, respectively. + type: string + required: + - keySelector + type: object + extendedProperties: + description: Extends the resolved identity object with additional + custom properties before appending to the authorization JSON. + It requires the resolved identity object to always be of the + JSON type 'object'. Other JSON types (array, string, etc) + will break. + items: + properties: + name: + description: The name of the JSON property + type: string + overwrite: + default: false + description: Whether the value should overwrite the value + of an existing property with the same name. + type: boolean + value: + description: Static value of the JSON property + x-kubernetes-preserve-unknown-fields: true + valueFrom: + description: Dynamic value of the JSON property + properties: + authJSON: + description: 'Selector to fetch a value from the authorization + JSON. It can be any path pattern to fetch from the + authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers are + available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and @strip.' + type: string + type: object + required: + - name + type: object + type: array + kubernetes: + properties: + audiences: + description: The list of audiences (scopes) that must be + claimed in a Kubernetes authentication token supplied + in the request, and reviewed by Authorino. If omitted, + Authorino will review tokens expecting the host name of + the requested protected service amongst the audiences. + items: + type: string + type: array + type: object + metrics: + default: false + description: Whether this identity config should generate individual + observability metrics + type: boolean + mtls: + properties: + allNamespaces: + default: false + description: Whether Authorino should look for TLS secrets + in all namespaces or only in the same namespace as the + AuthConfig. Enabling this option in namespaced Authorino + instances has no effect. + type: boolean + selector: + description: Label selector used by Authorino to match secrets + from the cluster storing trusted CA certificates to validate + clients trying to authenticate to this service + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, + NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists + or DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field + is "key", the operator is "In", and the values array + contains only "value". The requirements are ANDed. + type: object + type: object + required: + - selector + type: object + name: + description: The name of this identity source/authentication + mode. It usually identifies a source of identities or group + of users/clients of the protected service. It can be used + to refer to the resolved identity object in other configs. + type: string + oauth2: + properties: + credentialsRef: + description: Reference to a Kubernetes secret in the same + namespace, that stores client credentials to the OAuth2 + server. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + tokenIntrospectionUrl: + description: The full URL of the token introspection endpoint. + type: string + tokenTypeHint: + description: The token type hint for the token introspection. + If omitted, it defaults to "access_token". + type: string + required: + - credentialsRef + - tokenIntrospectionUrl + type: object + oidc: + properties: + endpoint: + description: Endpoint of the OIDC issuer. Authorino will + append to this value the well-known path to the OpenID + Connect discovery endpoint (i.e. "/.well-known/openid-configuration"), + used to automatically discover the OpenID Connect configuration, + whose set of claims is expected to include (among others) + the "jkws_uri" claim. The value must coincide with the + value of the "iss" (issuer) claim of the discovered OpenID + Connect configuration. + type: string + ttl: + description: Decides how long to wait before refreshing + the OIDC configuration (in seconds). + type: integer + required: + - endpoint + type: object + plain: + properties: + authJSON: + description: 'Selector to fetch a value from the authorization + JSON. It can be any path pattern to fetch from the authorization + JSON (e.g. ''context.request.http.host'') or a string + template with variable placeholders that resolve to patterns + (e.g. "Hello, {auth.identity.name}!"). Any patterns supported + by https://pkg.go.dev/github.com/tidwall/gjson can be + used. The following string modifiers are available: @extract:{sep:" + ",pos:0}, @replace{old:"",new:""}, @case:upper|lower, + @base64:encode|decode and @strip.' + type: string + type: object + priority: + default: 0 + description: Priority group of the config. All configs in the + same priority group are evaluated concurrently; consecutive + priority groups are evaluated sequentially. + type: integer + when: + description: Conditions for Authorino to enforce this identity + config. If omitted, the config will be enforced for all requests. + If present, all conditions must match for the config to be + enforced; otherwise, the config will be skipped. + items: + properties: + all: + description: A list of pattern expressions to be evaluated + as a logical AND. + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + any: + description: A list of pattern expressions to be evaluated + as a logical OR. + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + operator: + description: 'The binary operator to be applied to the + content fetched from the authorization JSON, for comparison + with "value". Possible values are: "eq" (equal to), + "neq" (not equal to), "incl" (includes; for arrays), + "excl" (excludes; for arrays), "matches" (regex)' + enum: + - eq + - neq + - incl + - excl + - matches + type: string + patternRef: + description: Name of a named pattern + type: string + selector: + description: Any pattern supported by https://pkg.go.dev/github.com/tidwall/gjson. + The value is used to fetch content from the input authorization + JSON built by Authorino along the identity and metadata + phases. + type: string + value: + description: The value of reference for the comparison + with the content fetched from the authorization JSON. + If used with the "matches" operator, the value must + compile to a valid Golang regex. + type: string + type: object + type: array + required: + - name + type: object + type: array + metadata: + description: List of metadata source configs. Authorino fetches JSON + content from sources on this list on every request. + items: + description: 'The metadata config. Apart from "name", one of the + following parameters is required and only one of the following + parameters is allowed: "http", userInfo" or "uma".' + properties: + cache: + description: Caching options for the external metadata fetched + when applying this config. Omit it to avoid caching metadata + from this source. + properties: + key: + description: Key used to store the entry in the cache. Cache + entries from different metadata configs are stored and + managed separately regardless of the key. + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from the + authorization JSON. It can be any path pattern + to fetch from the authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers are + available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and @strip.' + type: string + type: object + type: object + ttl: + default: 60 + description: Duration (in seconds) of the external data + in the cache before pulled again from the source. + type: integer + required: + - key + type: object + http: + description: Generic HTTP interface to obtain authorization + metadata from a HTTP service. + properties: + body: + description: Raw body of the HTTP request. Supersedes 'bodyParameters'; + use either one or the other. Use it with method=POST; + for GET requests, set parameters as query string in the + 'endpoint' (placeholders can be used). + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from the + authorization JSON. It can be any path pattern + to fetch from the authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers are + available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and @strip.' + type: string + type: object + type: object + bodyParameters: + description: Custom parameters to encode in the body of + the HTTP request. Superseded by 'body'; use either one + or the other. Use it with method=POST; for GET requests, + set parameters as query string in the 'endpoint' (placeholders + can be used). + items: + properties: + name: + description: The name of the JSON property + type: string + value: + description: Static value of the JSON property + x-kubernetes-preserve-unknown-fields: true + valueFrom: + description: Dynamic value of the JSON property + properties: + authJSON: + description: 'Selector to fetch a value from the + authorization JSON. It can be any path pattern + to fetch from the authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers + are available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and + @strip.' + type: string + type: object + required: + - name + type: object + type: array + contentType: + default: application/x-www-form-urlencoded + description: Content-Type of the request body. Shapes how + 'bodyParameters' are encoded. Use it with method=POST; + for GET requests, Content-Type is automatically set to + 'text/plain'. + enum: + - application/x-www-form-urlencoded + - application/json + type: string + credentials: + description: Defines where client credentials will be passed + in the request to the service. If omitted, it defaults + to client credentials passed in the HTTP Authorization + header and the "Bearer" prefix expected prepended to the + secret value. + properties: + in: + default: authorization_header + description: The location in the request where client + credentials shall be passed on requests authenticating + with this identity source/authentication mode. + enum: + - authorization_header + - custom_header + - query + - cookie + type: string + keySelector: + description: Used in conjunction with the `in` parameter. + When used with `authorization_header`, the value is + the prefix of the client credentials string, separated + by a white-space, in the HTTP Authorization header + (e.g. "Bearer", "Basic"). When used with `custom_header`, + `query` or `cookie`, the value is the name of the + HTTP header, query string parameter or cookie key, + respectively. + type: string + required: + - keySelector + type: object + endpoint: + description: Endpoint of the HTTP service. The endpoint + accepts variable placeholders in the format "{selector}", + where "selector" is any pattern supported by https://pkg.go.dev/github.com/tidwall/gjson + and selects value from the authorization JSON. E.g. https://ext-auth-server.io/metadata?p={context.request.http.path} + type: string + headers: + description: Custom headers in the HTTP request. + items: + properties: + name: + description: The name of the JSON property + type: string + value: + description: Static value of the JSON property + x-kubernetes-preserve-unknown-fields: true + valueFrom: + description: Dynamic value of the JSON property + properties: + authJSON: + description: 'Selector to fetch a value from the + authorization JSON. It can be any path pattern + to fetch from the authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers + are available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and + @strip.' + type: string + type: object + required: + - name + type: object + type: array + method: + default: GET + description: 'HTTP verb used in the request to the service. + Accepted values: GET (default), POST. When the request + method is POST, the authorization JSON is passed in the + body of the request.' + enum: + - GET + - POST + type: string + oauth2: + description: Authentication with the HTTP service by OAuth2 + Client Credentials grant. + properties: + cache: + default: true + description: Caches and reuses the token until expired. + Set it to false to force fetch the token at every + authorization request regardless of expiration. + type: boolean + clientId: + description: OAuth2 Client ID. + type: string + clientSecretRef: + description: Reference to a Kubernetes Secret key that + stores that OAuth2 Client Secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: The name of the secret in the Authorino's + namespace to select from. + type: string + required: + - key + - name + type: object + extraParams: + additionalProperties: + type: string + description: Optional extra parameters for the requests + to the token URL. + type: object + scopes: + description: Optional scopes for the client credentials + grant, if supported by he OAuth2 server. + items: + type: string + type: array + tokenUrl: + description: Token endpoint URL of the OAuth2 resource + server. + type: string + required: + - clientId + - clientSecretRef + - tokenUrl + type: object + sharedSecretRef: + description: Reference to a Secret key whose value will + be passed by Authorino in the request. The HTTP service + can use the shared secret to authenticate the origin of + the request. Ignored if used together with oauth2. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: The name of the secret in the Authorino's + namespace to select from. + type: string + required: + - key + - name + type: object + required: + - endpoint + type: object + metrics: + default: false + description: Whether this metadata config should generate individual + observability metrics + type: boolean + name: + description: The name of the metadata source. It can be used + to refer to the resolved metadata object in other configs. + type: string + priority: + default: 0 + description: Priority group of the config. All configs in the + same priority group are evaluated concurrently; consecutive + priority groups are evaluated sequentially. + type: integer + uma: + description: User-Managed Access (UMA) source of resource data. + properties: + credentialsRef: + description: Reference to a Kubernetes secret in the same + namespace, that stores client credentials to the resource + registration API of the UMA server. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + endpoint: + description: The endpoint of the UMA server. The value must + coincide with the "issuer" claim of the UMA config discovered + from the well-known uma configuration endpoint. + type: string + required: + - credentialsRef + - endpoint + type: object + userInfo: + description: OpendID Connect UserInfo linked to an OIDC identity + config of this same spec. + properties: + identitySource: + description: The name of an OIDC identity source included + in the "identity" section and whose OpenID Connect configuration + discovered includes the OIDC "userinfo_endpoint" claim. + type: string + required: + - identitySource + type: object + when: + description: Conditions for Authorino to apply this metadata + config. If omitted, the config will be applied for all requests. + If present, all conditions must match for the config to be + applied; otherwise, the config will be skipped. + items: + properties: + all: + description: A list of pattern expressions to be evaluated + as a logical AND. + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + any: + description: A list of pattern expressions to be evaluated + as a logical OR. + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + operator: + description: 'The binary operator to be applied to the + content fetched from the authorization JSON, for comparison + with "value". Possible values are: "eq" (equal to), + "neq" (not equal to), "incl" (includes; for arrays), + "excl" (excludes; for arrays), "matches" (regex)' + enum: + - eq + - neq + - incl + - excl + - matches + type: string + patternRef: + description: Name of a named pattern + type: string + selector: + description: Any pattern supported by https://pkg.go.dev/github.com/tidwall/gjson. + The value is used to fetch content from the input authorization + JSON built by Authorino along the identity and metadata + phases. + type: string + value: + description: The value of reference for the comparison + with the content fetched from the authorization JSON. + If used with the "matches" operator, the value must + compile to a valid Golang regex. + type: string + type: object + type: array + required: + - name + type: object + type: array + patterns: + additionalProperties: + items: + properties: + operator: + description: 'The binary operator to be applied to the content + fetched from the authorization JSON, for comparison with + "value". Possible values are: "eq" (equal to), "neq" (not + equal to), "incl" (includes; for arrays), "excl" (excludes; + for arrays), "matches" (regex)' + enum: + - eq + - neq + - incl + - excl + - matches + type: string + selector: + description: Any pattern supported by https://pkg.go.dev/github.com/tidwall/gjson. + The value is used to fetch content from the input authorization + JSON built by Authorino along the identity and metadata + phases. + type: string + value: + description: The value of reference for the comparison with + the content fetched from the authorization JSON. If used + with the "matches" operator, the value must compile to a + valid Golang regex. + type: string + type: object + type: array + description: Named sets of JSON patterns that can be referred in `when` + conditionals and in JSON-pattern matching policy rules. + type: object + response: + description: List of response configs. Authorino gathers data from + the auth pipeline to build custom responses for the client. + items: + description: 'Dynamic response to return to the client. Apart from + "name", one of the following parameters is required and only one + of the following parameters is allowed: "wristband" or "json".' + properties: + cache: + description: Caching options for dynamic responses built when + applying this config. Omit it to avoid caching dynamic responses + for this config. + properties: + key: + description: Key used to store the entry in the cache. Cache + entries from different metadata configs are stored and + managed separately regardless of the key. + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from the + authorization JSON. It can be any path pattern + to fetch from the authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers are + available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and @strip.' + type: string + type: object + type: object + ttl: + default: 60 + description: Duration (in seconds) of the external data + in the cache before pulled again from the source. + type: integer + required: + - key + type: object + json: + properties: + properties: + description: List of JSON property-value pairs to be added + to the dynamic response. + items: + properties: + name: + description: The name of the JSON property + type: string + value: + description: Static value of the JSON property + x-kubernetes-preserve-unknown-fields: true + valueFrom: + description: Dynamic value of the JSON property + properties: + authJSON: + description: 'Selector to fetch a value from the + authorization JSON. It can be any path pattern + to fetch from the authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers + are available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and + @strip.' + type: string + type: object + required: + - name + type: object + type: array + required: + - properties + type: object + metrics: + default: false + description: Whether this response config should generate individual + observability metrics + type: boolean + name: + description: Name of the custom response. It can be used to + refer to the resolved response object in other configs. + type: string + plain: + description: StaticOrDynamicValue is either a constant static + string value or a config for fetching a value from a dynamic + source (e.g. a path pattern of authorization JSON) + properties: + value: + description: Static value + type: string + valueFrom: + description: Dynamic value + properties: + authJSON: + description: 'Selector to fetch a value from the authorization + JSON. It can be any path pattern to fetch from the + authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders that + resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers are available: + @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and @strip.' + type: string + type: object + type: object + priority: + default: 0 + description: Priority group of the config. All configs in the + same priority group are evaluated concurrently; consecutive + priority groups are evaluated sequentially. + type: integer + when: + description: Conditions for Authorino to enforce this custom + response config. If omitted, the config will be enforced for + all requests. If present, all conditions must match for the + config to be enforced; otherwise, the config will be skipped. + items: + properties: + all: + description: A list of pattern expressions to be evaluated + as a logical AND. + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + any: + description: A list of pattern expressions to be evaluated + as a logical OR. + items: + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + operator: + description: 'The binary operator to be applied to the + content fetched from the authorization JSON, for comparison + with "value". Possible values are: "eq" (equal to), + "neq" (not equal to), "incl" (includes; for arrays), + "excl" (excludes; for arrays), "matches" (regex)' + enum: + - eq + - neq + - incl + - excl + - matches + type: string + patternRef: + description: Name of a named pattern + type: string + selector: + description: Any pattern supported by https://pkg.go.dev/github.com/tidwall/gjson. + The value is used to fetch content from the input authorization + JSON built by Authorino along the identity and metadata + phases. + type: string + value: + description: The value of reference for the comparison + with the content fetched from the authorization JSON. + If used with the "matches" operator, the value must + compile to a valid Golang regex. + type: string + type: object + type: array + wrapper: + default: httpHeader + description: How Authorino wraps the response. Use "httpHeader" + (default) to wrap the response in an HTTP header; or "envoyDynamicMetadata" + to wrap the response as Envoy Dynamic Metadata + enum: + - httpHeader + - envoyDynamicMetadata + type: string + wrapperKey: + description: The name of key used in the wrapped response (name + of the HTTP header or property of the Envoy Dynamic Metadata + JSON). If omitted, it will be set to the name of the configuration. + type: string + wristband: + properties: + customClaims: + description: Any claims to be added to the wristband token + apart from the standard JWT claims (iss, iat, exp) added + by default. + items: + properties: + name: + description: The name of the JSON property + type: string + value: + description: Static value of the JSON property + x-kubernetes-preserve-unknown-fields: true + valueFrom: + description: Dynamic value of the JSON property + properties: + authJSON: + description: 'Selector to fetch a value from the + authorization JSON. It can be any path pattern + to fetch from the authorization JSON (e.g. ''context.request.http.host'') + or a string template with variable placeholders + that resolve to patterns (e.g. "Hello, {auth.identity.name}!"). + Any patterns supported by https://pkg.go.dev/github.com/tidwall/gjson + can be used. The following string modifiers + are available: @extract:{sep:" ",pos:0}, @replace{old:"",new:""}, + @case:upper|lower, @base64:encode|decode and + @strip.' + type: string + type: object + required: + - name + type: object + type: array + issuer: + description: 'The endpoint to the Authorino service that + issues the wristband (format: ://:/, + where = /://:/, + where = /://:/, + where = / getAuthConfigs() { + return List.of( + new AuthConfigBuilder().build()); + } + + @Override + public String getName() { + return APP_NAME; + } + }; + private static final AuthorinoOperatorProvisioner provisioner = initializeOperatorProvisioner(); + + private static AuthorinoOperatorProvisioner initializeOperatorProvisioner() { + AuthorinoOperatorProvisioner operatorProvisioner = new AuthorinoOperatorProvisioner( + AUTHORINO_OPERATOR_APPLICATION); + return operatorProvisioner; + } + + @BeforeAll + public static void createOperatorGroup() throws IOException { + provisioner.configure(); + IntersmashExtension.operatorCleanup(); + // create operator group - this should be done by InteropExtension + OpenShifts.adminBinary().execute("apply", "-f", new OperatorGroup().save().getAbsolutePath()); + // clean any leftovers + provisioner.unsubscribe(); + // let's configure the provisioner + provisioner.configure(); + } + + @AfterAll + public static void removeOperatorGroup() { + OpenShifts.adminBinary().execute("delete", "operatorgroup", "--all"); + provisioner.dismiss(); + } + + @AfterEach + public void customResourcesCleanup() { + // delete the AuthConfig CR(s) + provisioner.authConfigs() + .forEach(authConfig -> authConfig.withPropagationPolicy(DeletionPropagation.FOREGROUND).delete()); + // delete the Authorino CR, first scaling it down to 0 (graceful shutdown) + provisioner.scale(0, Boolean.TRUE); + provisioner.authorino().withPropagationPolicy(DeletionPropagation.FOREGROUND).delete(); + } + + /** + * Test the Authorino Operator based provisioning model by validating the creation of a {@link Authorino} CR, + * as per the full example at https://github.com/Kuadrant/authorino-operator/blob/main/README.md#full-example + */ + @Test + public void fullExampleTest() { + provisioner.subscribe(); + try { + // create and verify that object exists + final Authorino testedAuthorinoResource = provisioner.getApplication().getAuthorino(); + provisioner.authorinosClient().createOrReplace(testedAuthorinoResource); + Assertions.assertEquals(1, provisioner.authorinosClient().list().getItems().size()); + + final String authorinoApplicationName = provisioner.getApplication().getName(); + OpenShifts.master().waiters().areExactlyNPodsReady(1, testedAuthorinoResource.getKind(), + authorinoApplicationName).waitFor(); + + // scaling down to 0 (graceful shutdown) + testedAuthorinoResource.getSpec().setReplicas(0); + provisioner.authorinosClient().replace(testedAuthorinoResource); + new SimpleWaiter( + () -> OpenShifts.master().getLabeledPods("authorino-resource", authorinoApplicationName).size() == 0) + .waitFor(); + + // delete and verify that object was removed + provisioner.authorinosClient().withName(authorinoApplicationName) + .withPropagationPolicy(DeletionPropagation.FOREGROUND) + .delete(); + new SimpleWaiter(() -> provisioner.authorinosClient().list().getItems().size() == 0) + .waitFor(); + } finally { + provisioner.unsubscribe(); + } + } +} diff --git a/testsuite/integration-tests/src/test/java/org/jboss/intersmash/testsuite/provision/openshift/ProvisionerCleanupTestCase.java b/testsuite/integration-tests/src/test/java/org/jboss/intersmash/testsuite/provision/openshift/ProvisionerCleanupTestCase.java index a9808c000..b02038433 100644 --- a/testsuite/integration-tests/src/test/java/org/jboss/intersmash/testsuite/provision/openshift/ProvisionerCleanupTestCase.java +++ b/testsuite/integration-tests/src/test/java/org/jboss/intersmash/testsuite/provision/openshift/ProvisionerCleanupTestCase.java @@ -18,6 +18,7 @@ import java.io.IOException; import java.util.stream.Stream; +import org.jboss.intersmash.provision.openshift.AuthorinoOperatorProvisioner; import org.jboss.intersmash.provision.openshift.Eap7ImageOpenShiftProvisioner; import org.jboss.intersmash.provision.openshift.Eap7LegacyS2iBuildTemplateProvisioner; import org.jboss.intersmash.provision.openshift.InfinispanOperatorProvisioner; @@ -68,7 +69,9 @@ private static Stream provisionerProvider() { , new PostgreSQLImageOpenShiftProvisioner( OpenShiftProvisionerTestBase.getPostgreSQLImageOpenShiftApplication()), new PostgreSQLTemplateOpenShiftProvisioner( - OpenShiftProvisionerTestBase.getPostgreSQLTemplateOpenShiftApplication())); + OpenShiftProvisionerTestBase.getPostgreSQLTemplateOpenShiftApplication()) + // Authorino + , new AuthorinoOperatorProvisioner(AuthorinoOperatorProvisionerTest.AUTHORINO_OPERATOR_APPLICATION)); } else if (IntersmashTestsuiteProperties.isProductizedTestExecutionProfileEnabled()) { return Stream.of( // RHDG @@ -82,7 +85,9 @@ private static Stream provisionerProvider() { , new RhSsoTemplateOpenShiftProvisioner(OpenShiftProvisionerTestBase.getHttpsRhSso()) // RHBK , new KeycloakOperatorProvisioner( - OpenShiftProvisionerTestBase.getKeycloakOperatorApplication())); + OpenShiftProvisionerTestBase.getKeycloakOperatorApplication()) + // Red Hat Authorino + , new AuthorinoOperatorProvisioner(AuthorinoOperatorProvisionerTest.AUTHORINO_OPERATOR_APPLICATION)); } else { throw new IllegalStateException( String.format("Unknown Intersmash test suite execution profile: %s",