diff --git a/modules/concepts/examples/authenticationclass-ldap-full.yaml b/modules/concepts/examples/authenticationclass-ldap-full.yaml new file mode 100644 index 000000000..746b18f78 --- /dev/null +++ b/modules/concepts/examples/authenticationclass-ldap-full.yaml @@ -0,0 +1,29 @@ +apiVersion: authentication.stackable.tech/v1alpha1 +kind: AuthenticationClass +metadata: + name: ldap-full +spec: + provider: + ldap: + hostname: my.ldap.server # <1> + port: 389 # <2> + searchBase: ou=users,dc=example,dc=org # <3> + searchFilter: (memberOf=cn=myTeam,ou=teams,dc=example,dc=org) # <4> + ldapFieldNames: # <5> + uid: uid + group: memberof + givenName: givenName + surname: sn + email: mail + bindCredentials: + secretClass: ldap-full-bind # <6> + scope: # <7> + pod: true + node: false + services: + - ldap-full + tls: # <8> + verification: + server: + caCert: + secretClass: ldap-full-ca-cert diff --git a/modules/concepts/examples/authenticationclass-ldap-openldap-simple.yaml b/modules/concepts/examples/authenticationclass-ldap-openldap-simple.yaml new file mode 100644 index 000000000..2331c41c3 --- /dev/null +++ b/modules/concepts/examples/authenticationclass-ldap-openldap-simple.yaml @@ -0,0 +1,32 @@ +apiVersion: authentication.stackable.tech/v1alpha1 +kind: AuthenticationClass +metadata: + name: openldap-simple +spec: + provider: + ldap: + hostname: my.openldap.server + port: 1389 + searchBase: ou=users,dc=example,dc=org + bindCredentials: + secretClass: openldap-simple-bind # <1> +--- +apiVersion: secrets.stackable.tech/v1alpha1 +kind: SecretClass +metadata: + name: openldap-simple-bind # <2> +spec: + backend: + k8sSearch: + searchNamespace: + pod: {} # <3> +--- +apiVersion: v1 +kind: Secret +metadata: + name: openldap-simple-bind # <4> + labels: + secrets.stackable.tech/class: openldap-simple-bind # <5> +stringData: + user: cn=admin,dc=example,dc=org + password: admin diff --git a/modules/concepts/examples/authenticationclass-ldap-simple.yaml b/modules/concepts/examples/authenticationclass-ldap-simple.yaml new file mode 100644 index 000000000..a7bfc03a3 --- /dev/null +++ b/modules/concepts/examples/authenticationclass-ldap-simple.yaml @@ -0,0 +1,10 @@ +apiVersion: authentication.stackable.tech/v1alpha1 +kind: AuthenticationClass +metadata: + name: ldap-simple +spec: + provider: + ldap: + hostname: my.ldap.server # <1> + port: 389 # <2> + searchBase: ou=users,dc=example,dc=org # <3> diff --git a/modules/concepts/examples/authenticationclass-static-authenticationclass.yaml b/modules/concepts/examples/authenticationclass-static-authenticationclass.yaml new file mode 100644 index 000000000..7c21e272b --- /dev/null +++ b/modules/concepts/examples/authenticationclass-static-authenticationclass.yaml @@ -0,0 +1,9 @@ +apiVersion: authentication.stackable.tech/v1alpha1 +kind: AuthenticationClass +metadata: + name: simple-users +spec: + provider: + static: + userCredentialsSecret: + name: simple-users-credentials # <1> diff --git a/modules/concepts/examples/authenticationclass-static-secret.yaml b/modules/concepts/examples/authenticationclass-static-secret.yaml new file mode 100644 index 000000000..d930d3c3f --- /dev/null +++ b/modules/concepts/examples/authenticationclass-static-secret.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Secret +metadata: + name: simple-users-credentials # <1> + namespace: default # <2> +type: kubernetes.io/opaque +stringData: + admin: admin + alice: superpass + bob: secret diff --git a/modules/concepts/examples/authenticationclass-tls.yaml b/modules/concepts/examples/authenticationclass-tls.yaml new file mode 100644 index 000000000..e2a4d07dc --- /dev/null +++ b/modules/concepts/examples/authenticationclass-tls.yaml @@ -0,0 +1,8 @@ +apiVersion: authentication.stackable.tech/v1alpha1 +kind: AuthenticationClass +metadata: + name: client-auth-tls +spec: + provider: + tls: + clientCertSecretClass: client-auth-tls diff --git a/modules/concepts/examples/tls-mutual-verification.yaml b/modules/concepts/examples/tls-mutual-verification.yaml new file mode 100644 index 000000000..c684bd4ed --- /dev/null +++ b/modules/concepts/examples/tls-mutual-verification.yaml @@ -0,0 +1,4 @@ +tls: + verification: + mutual: + certSecretClass: openldap-tls diff --git a/modules/concepts/examples/tls-no-verification.yaml b/modules/concepts/examples/tls-no-verification.yaml new file mode 100644 index 000000000..aab245d01 --- /dev/null +++ b/modules/concepts/examples/tls-no-verification.yaml @@ -0,0 +1,3 @@ +tls: + verification: + none: {} diff --git a/modules/concepts/examples/tls-server-verification-custom-ca.yaml b/modules/concepts/examples/tls-server-verification-custom-ca.yaml new file mode 100644 index 000000000..5ff8876bb --- /dev/null +++ b/modules/concepts/examples/tls-server-verification-custom-ca.yaml @@ -0,0 +1,5 @@ +tls: + verification: + server: + caCert: + secretClass: openldap-tls-ca diff --git a/modules/concepts/examples/tls-server-verification-webpki.yaml b/modules/concepts/examples/tls-server-verification-webpki.yaml new file mode 100644 index 000000000..82fc010e4 --- /dev/null +++ b/modules/concepts/examples/tls-server-verification-webpki.yaml @@ -0,0 +1,5 @@ +tls: + verification: + server: + caCert: + webPki: {} diff --git a/modules/concepts/examples/tls-simple.yaml b/modules/concepts/examples/tls-simple.yaml new file mode 100644 index 000000000..54adabd28 --- /dev/null +++ b/modules/concepts/examples/tls-simple.yaml @@ -0,0 +1,4 @@ +# [...] +tls: + verification: + none: {} diff --git a/modules/concepts/images/authenticationclass-ldap.plantuml b/modules/concepts/images/authenticationclass-ldap.plantuml new file mode 100644 index 000000000..55524ea07 --- /dev/null +++ b/modules/concepts/images/authenticationclass-ldap.plantuml @@ -0,0 +1,27 @@ +allowmixing + +database LDAP + +map "Secret openldap-simple-bind" as secret_openldap_simple_bind { + user => cn=admin,dc=example,dc=org + password => admin +} + +map "Secret openldap-simple-ca" as secret_openldap_simple_ca { + caCert => +} + +map "SecretClass openldap-simple-bind" as secret_class_openldap_simple_bind { + k8sSearch *-> secret_openldap_simple_bind +} + +map "SecretClass openldap-simple-ca" as secret_class_openldap_simple_ca { + k8sSearch *-> secret_openldap_simple_ca +} + +map "AuthenticationClass openldap-simple" as authentication_class_openldap_simple { + ldapHost *--> LDAP + tlsServerVerification *--> secret_class_openldap_simple_ca + bindCredentials *--> secret_class_openldap_simple_bind + ldapSearchBase => ou=users,dc=example,dc=org +} diff --git a/modules/concepts/nav.adoc b/modules/concepts/nav.adoc index 4284e7802..129516cea 100644 --- a/modules/concepts/nav.adoc +++ b/modules/concepts/nav.adoc @@ -1,8 +1,10 @@ * xref:concepts:index.adoc[] -** xref:roles-and-role-groups.adoc[] -** xref:service_discovery.adoc[] +** xref:authenticationclass.adoc[] ** xref:opa.adoc[] -** xref:s3.adoc[] +** xref:product_image_selection.adoc[] ** xref:pvc.adoc[] ** xref:resources.adoc[] -** xref:product_image_selection.adoc[] +** xref:roles-and-role-groups.adoc[] +** xref:s3.adoc[] +** xref:service_discovery.adoc[] +** xref:tls_server_verification.adoc[] diff --git a/modules/concepts/pages/authenticationclass.adoc b/modules/concepts/pages/authenticationclass.adoc new file mode 100644 index 000000000..6d3e2fc93 --- /dev/null +++ b/modules/concepts/pages/authenticationclass.adoc @@ -0,0 +1,94 @@ += `AuthenticationClass` + +`AuthenticationClass` is a CRD describing a generic authentication method like LDAP or Kerberos. +It has `cluster` scope, so it does not belong to a specific namespace. +Multiple operators use this CRD as a way to express and configure the authentication methods of their respective product. + +At the moment the following Authentication providers are supported: + +* <> +* <> +* <> + +== LDAP +A very simple `AuthenticationClass` with LDAP Authentication looks like this: + +[source,yaml] +---- +include::example$authenticationclass-ldap-simple.yaml[] +---- +<1> The hostname of the LDAP server without any protocol or port +<2> The port of the LDAP server. If TLS is used it defaults to `636` otherwise to `389` +<3> An optional searchBase where the users should be searched + +=== OpenLDAP +Here is an example that is tuned for an OpenLDAP server and is configured to read bind user credentials from a secret: + +[source,yaml] +---- +include::example$authenticationclass-ldap-openldap-simple.yaml[] +---- +<1> The name of the xref:secret-operator::secretclass.adoc[] providing the bind credentials (username and password). Must match the name of the xref:secret-operator::secretclass.adoc[] in this example in ② +<2> The name of the xref:secret-operator::secretclass.adoc[] we are creating that is referred to by ➀. See xref:secret-operator::secretclass.adoc[] +<3> This determines the namespace in which the referenced `Secret` will be looked for. In this case it searches for a `Secret` in the same namespace as the product runs in. See xref:secret-operator::secretclass.adoc#backend-k8ssearch[the documentation of SecretClass] +<4> The `Secret` containing the actual bind credentials. Please keep in mind that the `Secret` needs to be in the same namespace as the product +<5> The name of the xref:secret-operator::secretclass.adoc[] that refers to this `Secret`. Must match the name of the xref:secret-operator::secretclass.adoc[] in this example in ② + +The following diagram describes the relationship between the created CRDs + +[plantuml] +---- +include::image$authenticationclass-ldap.plantuml[] +---- + +=== All possible attributes +The following example shows all possible attributes: + +[source,yaml] +---- +include::example$authenticationclass-ldap-full.yaml[] +---- +<1> The hostname of the LDAP server without any protocol or port +<2> The port of the LDAP server. If TLS is used defaults to `636` otherwise to `389` +<3> The searchBase where the users should be searched +<4> Additional filter that filters the allowed users +<5> The name of the corresponding field names in the LDAP objects +<6> The name of the xref:secret-operator::secretclass.adoc[] providing the bind credentials (username and password) +<7> The xref:secret-operator::scope.adoc[] of the xref:secret-operator::secretclass.adoc[] +<8> xref:tls_server_verification.adoc[] of the LDAP server + +== TLS +The `TLS` provider configures a product to authenticate users using TLS certificates. +When establishing a connection the client will first validate the certificate of the server. +This step is not influenced by this `AuthenticationClass`, it only affects the next step: +Afterwards the server checks the validity of the certificate the client has provided. +This includes the usual checks - such as checking that it hasn't expired and matches the hostname of the client. +Additionally the client certificate needs to be signed with the `ca` certificate, which is provided by the `SecretClass` specified in `clientCertSecretClass`. + +A sample TLS provider looks as follows: + +[source,yaml] +---- +include::example$authenticationclass-tls.yaml[] +---- + +== Static +The `static` provider is used to represent a simple - static - set of users. +Users are identified by a username and a password. + +First of the `AuthenticationClass` needs to be defined as follows: + +[source,yaml] +---- +include::example$authenticationclass-static-authenticationclass.yaml[] +---- +<1> The name of the `Secret` containing the credentials + +Afterwards the referenced `Secret` needs to be created: + +[source,yaml] +---- +include::example$authenticationclass-static-secret.yaml[] +---- +<1> The name of the `Secret`, which needs to match the `Secret` name specified in the `AuthenticationClass` above +<2> The namespace of the `Secret`. The `Secret` needs to be in the same namespace as the product that tries to use the static `AuthenticationClass` diff --git a/modules/concepts/pages/tls_server_verification.adoc b/modules/concepts/pages/tls_server_verification.adoc new file mode 100644 index 000000000..1edf37b0d --- /dev/null +++ b/modules/concepts/pages/tls_server_verification.adoc @@ -0,0 +1,57 @@ += TLS server verification + +A TLS section is part of Stackable CRDs and describes how to connect to a TLS enabled system like LDAP or S3. + +If the `tls` attribute is set to `null` (or is not specified), no TLS will be used for the connection. + +A simple TLS section looks like this: + +[source,yaml] +---- +include::example$tls-simple.yaml[] +---- + +== Verification +The parties participating via a TLS connection can be verified using certificates. +At the moment the following verification methods are supported: + +* <> +* <> +* <> + +=== No verification +This example will use TLS but not perform any checks on the certificate presented by the server or present a client certificate if asked for one by the server. + +[source,yaml] +---- +include::example$tls-no-verification.yaml[] +---- + +=== Server verification +This example will use TLS and verify the server using the ca certificates that are trusted by common web browsers. +This can be useful when you e.g. use public AWS S3 or other public available services. + +[source,yaml] +---- +include::example$tls-server-verification-webpki.yaml[] +---- + +This example will use TLS and verify the server using the provided ca certificate. +For this to work you need to create a xref:secret-operator::secretclass.adoc[] that - at least - contains the ca certificate. +Note that a SecretClass does not need to have a key but can also work with just a ca cert. +So if you were provided with a ca cert but do not have access to the key you can still use this method. + +[source,yaml] +---- +include::example$tls-server-verification-custom-ca.yaml[] +---- + +=== Mutual verification +This example will use TLS and verify both - the server and the client using certificates. +For this to work you need to create a xref:secret-operator::secretclass.adoc[] containing the ca certificate and a key to create new client-certificates. +The xref:secret-operator::index.adoc[] will automatically provide the product with a `ca.crt`, `tls.crt` and `tls.key` so that the product can authenticate the server and it can authenticate itself at the server. + +[source,yaml] +---- +include::example$tls-mutual-verification.yaml[] +----