|
| 1 | +--- |
| 2 | +title: "Enable Single Sign-on (SSO) for OpenFaaS with Okta and OpenID Connect" |
| 3 | +description: "Learn how to enable Single Sign-on (SSO) for OpenFaaS with Okta and OpenID Connect." |
| 4 | +date: 2020-09-16 |
| 5 | +image: /images/2020-openfaas-arkade/briana.jpg |
| 6 | +categories: |
| 7 | + - kubernetes |
| 8 | + - developers |
| 9 | + - tools |
| 10 | + - oauth2 |
| 11 | + - oidc |
| 12 | +author_staff_member: alex |
| 13 | +dark_background: true |
| 14 | + |
| 15 | +--- |
| 16 | + |
| 17 | +Learn how to enable Single Sign-on (SSO) for OpenFaaS with Okta and OpenID Connect. |
| 18 | + |
| 19 | +## Enterprise authentication |
| 20 | + |
| 21 | +OpenID Connect is a common standard that builds upon OAuth2 to enable authentication to services and applications. Solutions like Okta can be used to enable Single Sign-On across a number of third-party and in-house applications. This reduces the burden on IT administrators - fewer requests to reset passwords, fewer employees will share credentials and policy can enforced in one place. |
| 22 | + |
| 23 | +In this tutorial, I'll show you how to setup Okta and OpenFaaS with the OIDC auth plugin. The OIDC auth plugin for OpenFaaS is a commercial add-on included in our Premium OpenFaaS Subscription. |
| 24 | + |
| 25 | +> [Apply for a trial here](https://forms.gle/mFmwtoez1obZzm286) |
| 26 | +
|
| 27 | +## Overview |
| 28 | + |
| 29 | +* Create a developer account with Okta |
| 30 | +* Register a domain or DNS sub-zone |
| 31 | +* Create an App in Okta |
| 32 | +* Collect OIDC URLS, IDs and credentials |
| 33 | +* Setup OpenFaaS with TLS, Ingress and the auth plugin |
| 34 | +* Configure your DNS |
| 35 | +* Test out logging into OpenFaaS with Okta |
| 36 | + |
| 37 | +## Tutorial |
| 38 | + |
| 39 | +### Create a developer account with Okta |
| 40 | + |
| 41 | +Head over to [developer.okta.com](https://developer.okta.com) and create a developer account. |
| 42 | + |
| 43 | +### Register a domain or DNS sub-zone |
| 44 | + |
| 45 | +You will need to register a domain, or to setup a sub-zone if you already own a domain. |
| 46 | + |
| 47 | +I'll be using the zone `.oauth.openfaas.pro` and then adding two entries later on in a later step. |
| 48 | + |
| 49 | +[Google Domains](https://domains.google.com) provide a cost-effective option. |
| 50 | + |
| 51 | +### Create an App in Okta |
| 52 | + |
| 53 | +We will have two URLs for OpenFaaS: |
| 54 | + |
| 55 | +* `gw.oauth.openfaas.pro` - the OpenFaaS gateway |
| 56 | +* `auth.oauth.openfaas.pro` - the OpenFaaS OIDC connector |
| 57 | + |
| 58 | +You will note that we are using the second domain here: `auth.oauth.openfaas.pro` |
| 59 | + |
| 60 | +A valid redirect domain of `http://127.0.0.1:31111/oauth/callback` is also required if you plan to use the `faas-cli` to authenticate to OpenFaaS. |
| 61 | + |
| 62 | + |
| 63 | + |
| 64 | +### Collect OIDC URLs, IDs and credentials |
| 65 | + |
| 66 | +Collect your various URLs, IDs and credentials |
| 67 | + |
| 68 | +Get the `client_id` and `secret` values: |
| 69 | + |
| 70 | + |
| 71 | + |
| 72 | +I was assigned a random domain of `dev-624219`, the corresponding URLs will be `dev-624219.okta.com`. |
| 73 | + |
| 74 | +```bash |
| 75 | +export yourOktaDomain=dev-624219.okta.com |
| 76 | +export authServerId=default |
| 77 | + |
| 78 | +curl -s https://${yourOktaDomain}/oauth2/${authServerId}/.well-known/openid-configuration |
| 79 | +``` |
| 80 | + |
| 81 | +If you pipe the result to `jq`, or save it as JSON and format it, you'll see the important URLs that OpenFaaS needs: |
| 82 | + |
| 83 | +```json |
| 84 | +{ |
| 85 | + "issuer": "https://dev-624219.okta.com/oauth2/default", |
| 86 | + "authorization_endpoint": "https://dev-624219.okta.com/oauth2/default/v1/authorize", |
| 87 | + "token_endpoint": "https://dev-624219.okta.com/oauth2/default/v1/token", |
| 88 | + "userinfo_endpoint": "https://dev-624219.okta.com/oauth2/default/v1/userinfo", |
| 89 | + "registration_endpoint": "https://dev-624219.okta.com/oauth2/v1/clients", |
| 90 | + "jwks_uri": "https://dev-624219.okta.com/oauth2/default/v1/keys" |
| 91 | +} |
| 92 | +``` |
| 93 | + |
| 94 | +You should set the `cookieDomain` to the domain or DNS-zone that was created. |
| 95 | + |
| 96 | +Fill out the following and save it as `install.sh`, but do not run it yet. |
| 97 | + |
| 98 | +```bash |
| 99 | +export PROVIDER="" # Set this to "azure" if using Azure AD. |
| 100 | +export LICENSE="" |
| 101 | +export OAUTH_CLIENT_SECRET="" |
| 102 | +export OAUTH_CLIENT_ID="" |
| 103 | + |
| 104 | +arkade install openfaas \ |
| 105 | + --set oauth2Plugin.enabled=true \ |
| 106 | + --set oauth2Plugin.provider=$PROVIDER \ |
| 107 | + --set oauth2Plugin.license=$LICENSE \ |
| 108 | + --set oauth2Plugin.insecureTLS=false \ |
| 109 | + --set oauth2Plugin.scopes="openid profile email" \ |
| 110 | + --set oauth2Plugin.jwksURL=https://dev-624219.okta.com/oauth2/default/v1/keys \ |
| 111 | + --set oauth2Plugin.tokenURL=https://dev-624219.okta.com/oauth2/default/v1/token \ |
| 112 | + --set oauth2Plugin.audience=https://gw.oauth.openfaas.pro \ |
| 113 | + --set oauth2Plugin.authorizeURL=https://dev-624219.okta.com/oauth2/default/v1/authorize \ |
| 114 | + --set oauth2Plugin.welcomePageURL=https://gw.oauth.openfaas.pro \ |
| 115 | + --set oauth2Plugin.cookieDomain=.oauth.openfaas.pro \ |
| 116 | + --set oauth2Plugin.baseHost=https://auth.oauth.openfaas.pro \ |
| 117 | + --set oauth2Plugin.clientSecret=$OAUTH_CLIENT_SECRET \ |
| 118 | + --set oauth2Plugin.clientID=$OAUTH_CLIENT_ID |
| 119 | +``` |
| 120 | + |
| 121 | +If you're using a GitOps tool or helm to install OpenFaaS, then the above options can be written into your `values.yaml` file instead. The `clientSecret` is a confidential value, so don't commit this to a public repo. |
| 122 | + |
| 123 | +For instance: |
| 124 | + |
| 125 | +```yaml |
| 126 | +... |
| 127 | +oauth2Plugin: |
| 128 | + enabled: true |
| 129 | + jwksURL: https://dev-624219.okta.com/oauth2/default/v1/keys |
| 130 | +... |
| 131 | +``` |
| 132 | + |
| 133 | +### Setup OpenFaaS with TLS, Ingress and the auth plugin |
| 134 | + |
| 135 | +Before running the `install.sh` script, you'll either need a public Kubernetes cluster, or a private/on-premises cluster using [inlets PRO](https://inlets.dev) to provide a LoadBalancer with a public IP. |
| 136 | + |
| 137 | +Install an IngressController if you don't already have one: |
| 138 | + |
| 139 | +```bash |
| 140 | +arkade install ingress-nginx |
| 141 | +``` |
| 142 | + |
| 143 | +Install cert-manager if you don't already have it: |
| 144 | + |
| 145 | +```bash |
| 146 | +arkade install cert-manager |
| 147 | +``` |
| 148 | + |
| 149 | +Install OpenFaaS using `install.sh`. Note that if you have got a setting wrong, you can edit install.sh and run it again at any time. |
| 150 | + |
| 151 | +Create a TLS and Ingress record for the gateway: |
| 152 | + |
| 153 | +```bash |
| 154 | +arkade install openfaas-ingress \ |
| 155 | + --email alex@oauth.openfaas.pro \ |
| 156 | + --domain gw.oauth.openfaas.pro |
| 157 | +``` |
| 158 | + |
| 159 | +We need one more Ingress record for the OIDC provider, but arkade can't do that for us yet. |
| 160 | + |
| 161 | +Export the gateway's YAML file, edit the domain and name and apply it again: |
| 162 | + |
| 163 | +```bash |
| 164 | +kubectl get -n openfaas ingress/openfaas-gateway -o yaml \ |
| 165 | + --export > oauth2-plugin.yaml |
| 166 | +``` |
| 167 | + |
| 168 | +Edit `oauth2-plugin.yaml` |
| 169 | + |
| 170 | +Change the name from `openfaas-gateway` to `oauth2-plugin`, domain to `auth.oauth.openfaas.pro`, the host to `oidc`, and the secretName to `oauth2-plugin`. |
| 171 | + |
| 172 | +Alternatively use `sed`: |
| 173 | + |
| 174 | +```bash |
| 175 | +sed -ie s/openfaas-gateway/oauth2-plugin/g oauth2-plugin.yaml |
| 176 | +sed -ie s/gw./auth./g oauth2-plugin.yaml |
| 177 | +sed -ie s/gateway/oauth2-plugin/g oauth2-plugin.yaml |
| 178 | +``` |
| 179 | + |
| 180 | +Apply the changed file, forcing the namespace to `openfaas`: |
| 181 | + |
| 182 | +```bash |
| 183 | +kubectl apply -f oauth2-plugin -n openfaas |
| 184 | +``` |
| 185 | + |
| 186 | +### Configure your DNS |
| 187 | + |
| 188 | +Your TLS certs cannot be issued until you create some DNS records. |
| 189 | + |
| 190 | +Run the following: |
| 191 | + |
| 192 | +```bash |
| 193 | +kubectl get svc ingress-nginx-controller |
| 194 | +``` |
| 195 | + |
| 196 | +If you have an IP address showing under `EXTERNAL-IP`, then create two A records for the two subdomains. If you see a DNS record, as per AWS EKS, then create a CNAME for them instead. |
| 197 | + |
| 198 | +* `gw.oauth.openfaas.pro` |
| 199 | +* `auth.oauth.openfaas.pro` |
| 200 | + |
| 201 | +Check that the DNS entries have propagated using `ping -c 1 gw.oauth.openfaas.pro` |
| 202 | + |
| 203 | +In a few moments you should see both certificates created: |
| 204 | + |
| 205 | +```bash |
| 206 | +kubectl get cert -n openfaas |
| 207 | +``` |
| 208 | + |
| 209 | +If you think there's a problem, run `kubectl describe -n openfaas order` |
| 210 | + |
| 211 | +### Test out logging into OpenFaaS with Okta |
| 212 | + |
| 213 | +We have now configured a Kubernetes cluster with an IngressController, cert-manager and OpenFaaS with the OIDC auth add-on. It's time to try logging in. |
| 214 | + |
| 215 | +Head over to the gateway's UI in a browser: |
| 216 | + |
| 217 | +``` |
| 218 | +https://gw.oauth.openfaas.pro |
| 219 | +``` |
| 220 | + |
| 221 | +> Note: If you're seeing a certificate error and the "Kubernetes Ingress Controller Fake Certificate" CA, then you need to go back to the previous step and double-check everything. Even if the DNS configuration is correct, it can take a few minutes for the certificate to be issued. |
| 222 | +
|
| 223 | +You should be redirected to your Okta developer domain, where you will be asked to log in with the user in Okta. |
| 224 | + |
| 225 | + |
| 226 | + |
| 227 | +View the portal: |
| 228 | + |
| 229 | + |
| 230 | + |
| 231 | +You can also log into OpenFaaS using the CLI for use on your laptop using the `faas-cli auth` command to obtain and store a token. |
| 232 | + |
| 233 | +```bash |
| 234 | +export CLIENT_ID="0oazbx89opTdXdOql4x6" |
| 235 | +faas-cli auth \ |
| 236 | + --client-id $CLIENT_ID \ |
| 237 | + --auth-url https://dev-624219.okta.com/oauth2/default/v1/authorize \ |
| 238 | + --gateway https://gw.oauth.openfaas.pro \ |
| 239 | + --grant implicit-id |
| 240 | +``` |
| 241 | + |
| 242 | +> Note: some OIDC providers like Azure Active Directory require "localhost" instead of 127.0.0.1 to be given for this flow. You can provide `--redirect-host=localhost` when using Azure. |
| 243 | +
|
| 244 | +```bash |
| 245 | +Starting local token server on port 31111 |
| 246 | + |
| 247 | +credentials saved for https://gw.oauth.openfaas.pro |
| 248 | + |
| 249 | +Example usage: |
| 250 | + # Use an explicit token |
| 251 | + faas-cli list --gateway "https://gw.oauth.openfaas.pro" --token "REDACTED" |
| 252 | + |
| 253 | + # Use the saved token |
| 254 | + faas-cli list --gateway "https://gw.oauth.openfaas.pro" |
| 255 | +``` |
| 256 | + |
| 257 | +Then you can use `faas-cli` from your machine using the token: |
| 258 | + |
| 259 | +```bash |
| 260 | +faas-cli list --gateway "https://gw.oauth.openfaas.pro" |
| 261 | +Function Invocations Replicas |
| 262 | +nodeinfo 0 1 |
| 263 | +``` |
| 264 | + |
| 265 | +When you need to use a token from CI, we provide instructions for the `clients_credentials` flow in the OpenFaaS documentation (referenced in the summary). |
| 266 | + |
| 267 | +## Wrapping up |
| 268 | + |
| 269 | +In a relatively short period of time, we've been able to authenticate to OpenFaaS using Okta and a single login. Any OIDC provider should work and I've tested the code with GitLab, Auth0 and GitLab so far. From here, it's easy to add other users to the OpenFaaS app, and to send them an invite over email to join. |
| 270 | + |
| 271 | +### What about authorization? |
| 272 | + |
| 273 | +Today the authorization piece is still limited. Any valid users who are in the correct group for the OpenFaaS App in Okta will be administrators in OpenFaaS. So whilst they won't have `kubectl` access, they will be able to perform CRUD operations on functions using `faas-cli`, the UI and the REST API. |
| 274 | + |
| 275 | +OpenFaaS has multiple-namespace support, and adding authorization is within sights. Do you want to see authorization on a per namespace basis? Do you need it per function? Would read-only roles be a valuable addition? |
| 276 | + |
| 277 | +Perhaps just adding OpenID Connect with Okta, Auth0, or GitLab to your corporate OpenFaaS deployment is enough, or maybe you need finer-grained authorization. I'd like to hear from you. |
| 278 | + |
| 279 | +You can contact me at [alex@openfaas.com](mailto:alex@openfaas.com) |
| 280 | + |
| 281 | +See also: |
| 282 | + |
| 283 | +* [Multiple namespace support](https://docs.openfaas.com/reference/namespaces/) |
| 284 | +* [Join the Slack community](https://slack.openfaas.io/) |
| 285 | +* [Authentication documentation](https://docs.openfaas.com/reference/authentication/) |
0 commit comments