AuthServer

AuthServer represents the request for an OIDC authorization server. It results in the deployment of an authorization server backed by Redis over mTLS.

An AuthServer should have labels which allow to uniquely match it amongst others. ClientRegistration selects an AuthServer by label selector and needs a unique match to be successful.

To allow ClientRegistrations from all or a restricted set of Namespaces, the annotation sso.apps.tanzu.vmware.com/allow-client-namespaces must be set. Its value is a comma-separated list of allowed Namespaces, e.g. "app-team-red,app-team-green", or "*" if it should allow clients from all namespaces. If the annotation is missing, no clients are allowed.

An AuthServer has a spec.issuerURI which is the entry point for clients and end-users. A form of Ingress needs to be configured for this issuer URI.

Token signature keys are configured through spec.tokenSignature. If no keys are configured, no tokens can be minted.

Identity providers are configured under spec.identityProviders. If there are none, end-users won’t be able to log in.

The deployment can be further customized by configuring replicas, resources, http server and logging properties.

An AuthServer reconciles into the following resources in its namespace:

AuthServer/my-authserver
├─Certificate/my-authserver-redis-client
├─Certificate/my-authserver-redis-server
├─Certificate/my-authserver-root
├─ConfigMap/my-authserver-ca-cert
├─Deployment/my-authserver-auth-server
├─Deployment/my-authserver-redis
├─Issuer/my-authserver-bootstrap
├─Issuer/my-authserver-root
├─Role/my-authserver-auth-server
├─RoleBinding/my-authserver-auth-server
├─Secret/my-authserver-auth-server-clients
├─Secret/my-authserver-auth-server-keys
├─Secret/my-authserver-auth-server-properties
├─Secret/my-authserver-redis-client-cert-keystore-password
├─Secret/my-authserver-registry-credentials
├─Service/my-authserver-redis
└─ServiceAccount/my-authserver-auth-server

Spec

apiVersion: sso.apps.tanzu.vmware.com/v1alpha1
kind: AuthServer
metadata:
  name: ""
  namespace: ""
  labels: { }
  annotations:
    sso.apps.tanzu.vmware.com/allow-client-namespaces: ""
spec:
  issuerURI: "" # required
  tokenSignature: # optional
    signAndVerifyKeyRef:
      name: ""
    extraVerifyKeyRefs:
      - name: ""
  identityProviders: # optional
    # each must be one and only one of internalUnsafe, ldap, openID or saml
    - name: "" # must be unique
      internalUnsafe: # requires annotation `sso.apps.tanzu.vmware.com/allow-unsafe-identity-provider: ""`
        users:
          - username: ""
            password: ""
            roles:
              - ""
    - name: "" # must be unique
      ldap:
        server:
          scheme: ""
          host: ""
          port: 0
          base: ""
        bind:
          dn: ""
          passwordRef:
            name: ldap-password
        user:
          searchFilter: ""
          searchBase: ""
        group:
          searchFilter: ""
          searchBase: ""
          searchSubTree: false
          searchDepth: 0
          roleAttribute: ""
    - name: "" # must be unique
      openID:
        issuerURI: ""
        clientID: ""
        clientSecretRef:
          name: ""
        scopes:
          - ""
    - name: "" # must be unique
      saml:
        metadataURI: ""
        claimMappings: { }
  replicas: 1 # optional, default 2
  logging: "" # optional, must be valid YAML
  server: "" # optional, must be valid YAML
  resources: # optional, default {requests: {cpu: "256m", memory: "300Mi"}, limits: {cpu: "2", memory: "768Mi"}}
    requests:
      cpu: ""
      mem: ""
    limits:
      cpu: ""
      mem: ""
  redisResources: # optional, default {requests: {cpu: "50m", memory: "100Mi"}, limits: {cpu: "100m", memory: "256Mi"}}
    requests:
      cpu: ""
      mem: ""
    limits:
      cpu: ""
      mem: ""
status:
  observedGeneration: 0
  clientRegistrationCount: 1
  tokenSignatureKeyCount: 0
  deployments:
    authServer:
      LastParentGenerationWithRestart: 0
      configHash: ""
      image: ""
      replicas: 0
    redis:
      image: ""
  conditions:
    - lastTransitionTime:
      message: ""
      reason: ""
      status: "True" # or "False" 
      type: ""

Alternatively, you can interactively discover the spec with:

kubectl explain authservers.sso.apps.tanzu.vmware.com

Status & conditions

The .status subresource helps you to learn the AuthServer’s readiness, resulting deployments, attached clients and to troubleshoot issues.

.status.tokenSignatureKeyCount is the number of currently configured token signature keys.

.status.clientRegistrationCount is the number of currently registered clients.

.status.deployments.authServer describes the current authorization server deployment by listing the running image, its replicas, the hash of the current configuration and the generation which has last resulted in a restart.

.status.deployments.redis describes the current Redis deployment by listing its running image.

.status.conditions documents each step in the reconciliation:

  • Valid: Is the spec valid?
  • ImagePullSecretApplied: Has the image pull secret been applied?
  • SignAndVerifyKeyResolved: Has the single sign-and-verify key been resolved?
  • ExtraVerifyKeysResolved: Have the single extra verify keys been resolved?
  • IdentityProvidersResolved: Has all identity provider configuration been resolved?
  • ConfigResolved: Has the complete configuration for the authorization server been resolved?
  • AuthServerConfigured: Has the complete configuration for the authorization server been applied?
  • IssuerURIReady: Is the authorization server yet responding to {spec.issuerURI}/.well-known/openid-configuration?
  • Ready: whether all the previous conditions are “True”

The super condition Ready denotes a fully successful reconciliation of a given ClientRegistration.

If everything goes well you will see something like this:

status:
  observedGeneration: 1
  tokenSignatureKeyCount: 3
  clientRegistrationCount: 1
  deployments:
    authServer:
      LastParentGenerationWithRestart: 1
      configHash: "13146309071473757471"
      image: dev.registry.tanzu.vmware.com/sso-for-kubernetes/authserver@sha256:9c761dd21bdd54cf8bf0de3cb23e04d75dcdedbbeee82bb78f6d3419c1c748ea
      replicas: 1
    redis:
      image: dev.registry.tanzu.vmware.com/sso-for-kubernetes/redis@sha256:3906dfa3d49b340ffc85c05890ddca7e5a9c775344c9b9d3bacda9bb6efac191
  conditions:
    - lastTransitionTime: "2022-05-13T08:29:55Z"
      message: ""
      reason: KeysConfigSecretUpdated
      status: "True"
      type: AuthServerConfigured
    - lastTransitionTime: "2022-05-13T08:29:54Z"
      message: ""
      reason: Resolved
      status: "True"
      type: ConfigResolved
    - lastTransitionTime: "2022-05-13T08:29:54Z"
      message: ""
      reason: ExtraVerifyKeysResolved
      status: "True"
      type: ExtraVerifyKeysResolved
    - lastTransitionTime: "2022-05-13T08:29:54Z"
      message: ""
      reason: Resolved
      status: "True"
      type: IdentityProvidersResolved
    - lastTransitionTime: "2022-05-13T08:29:54Z"
      message: ""
      reason: ImagePullSecretApplied
      status: "True"
      type: ImagePullSecretApplied
    - lastTransitionTime: "2022-05-13T09:04:22Z"
      message: ""
      reason: Ready
      status: "True"
      type: IssuerURIReady
    - lastTransitionTime: "2022-05-13T09:04:22Z"
      message: ""
      reason: Ready
      status: "True"
      type: Ready
    - lastTransitionTime: "2022-05-13T08:29:54Z"
      message: ""
      reason: SignAndVerifyKeyResolved
      status: "True"
      type: SignAndVerifyKeyResolved
    - lastTransitionTime: "2022-05-13T08:29:54Z"
      message: ""
      reason: Valid
      status: "True"
      type: Valid

RBAC

The ServiceAccount of the authorization server has a Role with the following permissions:

- apiGroups:
    - ""
  resources:
    - secrets
  verbs:
    - get
    - list
    - watch
  resourceNames:
    - { name }-auth-server-keys
    - { name }-auth-server-clients 

Example

This example requests an authorization server with the issuer URI http://authserver-sample.default, two token signature keys and two identity providers. It also configures ingress as you would on a local Kind cluster.

---
apiVersion: sso.apps.tanzu.vmware.com/v1alpha1
kind: AuthServer
metadata:
  name: authserver-sample
  namespace: default
  labels:
    name: authserver-sample
    sample: "true"
  annotations:
    sso.apps.tanzu.vmware.com/allow-client-namespaces: "*"
    sso.apps.tanzu.vmware.com/allow-unsafe-identity-provider: ""
    sso.apps.tanzu.vmware.com/allow-unsafe-issuer-uri: ""
spec:
  replicas: 1
  issuerURI: http://authserver-sample.default
  tokenSignature:
    signAndVerifyKeyRef:
      name: sample-token-signing-key
    extraVerifyKeyRefs:
      - name: sample-token-verification-key
  identityProviders:
    - name: internal
      internalUnsafe:
        users:
          - username: test-user-1
            password: $2a$10$201z9o/tHlocFsHFTo0plukh03ApBYe4dRiXcqeyRQH6CNNtS8jWK #! bcrypt-encoded "password"
            roles:
              - message.write
          - username: test-user-2
            password: $2a$10$201z9o/tHlocFsHFTo0plukh03ApBYe4dRiXcqeyRQH6CNNtS8jWK #! bcrypt-encoded "password"
            roles:
              - message.read
    - name: okta
      openID:
        issuerURI: https://dev-xxxxxx.okta.com
        clientID: xxxxxxxxxxxxx
        clientSecretRef:
          name: okta-client-secret
        authorizationUri: https://dev-xxxxxx.okta.com/oauth2/v1/authorize
        tokenUri: https://dev-xxxxxx.okta.com/oauth2/v1/token
        jwksUri: https://dev-xxxxxx.okta.com/oauth2/v1/keys
        scopes:
          - openid
        claimMappings:
          roles: my_custom_okta_roles_claim

---
apiVersion: secretgen.k14s.io/v1alpha1
kind: RSAKey
metadata:
  name: sample-token-signing-key
  namespace: default
spec:
  secretTemplate:
    type: Opaque
    stringData:
      key.pem: $(privateKey)
      pub.pem: $(publicKey)

---
apiVersion: secretgen.k14s.io/v1alpha1
kind: RSAKey
metadata:
  name: sample-token-verification-key
  namespace: default
spec:
  secretTemplate:
    type: Opaque
    stringData:
      key.pem: $(privateKey)
      pub.pem: $(publicKey)

---
apiVersion: v1
kind: Secret
metadata:
  name: okta-client-secret
  namespace: default
stringData:
  clientSecret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

---
apiVersion: v1
kind: Service
metadata:
  name: authserver-sample
  namespace: default
spec:
  selector:
    app.kubernetes.io/part-of: authserver-sample
    app.kubernetes.io/component: authorization-server
  ports:
    - port: 80
      targetPort: 8080

---
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
  name: authserver-sample
  namespace: default
spec:
  virtualhost:
    fqdn: authserver-sample.default
  routes:
    - conditions:
        - prefix: /
      services:
        - name: authserver-sample
          port: 80
check-circle-line exclamation-circle-line close-line
Scroll to top icon