~/authlab

authlab

A personal lab for working on identity, access, and the infrastructure around them.

Highlight part of the diagram
How a sign-in moves through the lab A person reaches lab applications, such as Grafana, through Cloudflare Access, which signs them in with Okta and checks their group. Okta pulls users and groups from an OpenLDAP directory through the Okta LDAP agent. identity sign in with Okta, check group LDAP agent person cloudflare access gate at the edge lab apps checks its own groups okta identity provider openldap directory source grafana
Terraform file
resource "okta_group" "cf_access_users" {
  description = "Cloudflare Access app assignment - populated via rules only"
  name        = "cf-access-users"
}

resource "okta_group" "all_grafana_users" {
  description = "Grafana dashboard tile assignment - populated via rules only"
  name        = "all-grafana-users"
}

resource "okta_group" "app_grafana_admins" {
  description = "Grafana entitlement - Admin role"
  name        = "app-grafana-admins"
}

resource "okta_group" "app_grafana_viewers" {
  description = "Grafana entitlement - Viewer role"
  name        = "app-grafana-viewers"
}
  • cf-access-users is the only group on the Cloudflare Access app
  • all-grafana-users puts the Grafana tile on the Okta dashboard
  • app-grafana-* groups map to Grafana admin and viewer roles
  • Both rollup groups are filled by rules, never by hand
resource "okta_group_rule" "cf_access_apps_rollup" {
  expression_type   = "urn:okta:expression:1.0"
  expression_value  = "Arrays.size(user.getGroups({'group.profile.name': 'app-', 'operator': 'STARTS_WITH'})) > 0"
  group_assignments = [okta_group.cf_access_users.id]
  name              = "cf-access-apps-rollup"
  status            = "ACTIVE"
}

resource "okta_group_rule" "grafana_users_rollup" {
  expression_type   = "urn:okta:expression:1.0"
  expression_value  = "isMemberOfAnyGroup(\"${okta_group.app_grafana_admins.id}\",\"${okta_group.app_grafana_viewers.id}\")"
  group_assignments = [okta_group.all_grafana_users.id]
  name              = "grafana-users-rollup"
  status            = "ACTIVE"
}
  • Any app-* group adds the user to cf-access-users
  • Either Grafana group adds the user to all-grafana-users
  • Groups are referenced by Terraform, so no IDs are written in the code
# Home network: the only location the Okta API token is allowed from.
resource "okta_network_zone" "home_authlab" {
  name     = "Authlab-Home"
  type     = "IP"
  usage    = "POLICY"
  gateways = var.home_gateways
}
  • Okta accepts Terraform's API token only from this zone
  • The addresses come from a variable in variables.tf
variable "home_gateways" {
  description = "Public IP addresses or CIDRs of the home network, used by the Authlab-Home network zone"
  type        = list(string)
}
  • Only the declaration lives in the code
  • The addresses sit in a local tfvars file that is never published
  • Cloudflare Access gates every lab app at the edge
  • Okta signs the person in, and Access checks their group
  • Each app then checks its own groups
  • OpenLDAP is the source for users and groups
  • The Okta LDAP agent syncs them into Okta
  • Passwords are verified against the directory itself

What's in the lab

open

One token, two validators

An interactive walkthrough that follows the same kind of OIDC token through two federation flows. A CI job with no stored credentials exchanges its token for Google Cloud access, and an Okta token for a person is checked by a Kubernetes API server against its own configuration. Each step decodes the token and shows which checks accept or reject it.

  • workload identity · 4 steps
  • workforce identity · 3 steps

Layered access with Okta groups

An Okta group rule written in Okta Expression Language rolls every application entitlement into one group, and Cloudflare Zero Trust Access authorizes only that group at the edge. Grafana then maps the same groups to admin or viewer roles. When an entitlement changes, access follows automatically.

# okta group rule: cf-access-apps-rollup
IF   Arrays.size(user.getGroups({
       'group.profile.name': 'app-',
       'operator': 'STARTS_WITH'
     })) > 0
THEN assign to cf-access-users

Membership in any group whose name starts with app adds the user to cf-access-users, the only group assigned to the Cloudflare Access app in Okta.

An LDAP directory feeding Okta

OpenLDAP supplies users and groups to Okta through the LDAP agent, with delegated authentication so every password is verified against the directory itself. Testing how authentication behaves while the agent is offline led to a detailed look at how Okta caches delegated credentials.

Keyless access to Google Cloud

CI jobs authenticate to Google Cloud through Workload Identity Federation, leaving no service account keys to store, rotate, or leak. The infrastructure is split into a persistent foundation and a cluster that is created and torn down for each session, all defined in Terraform.

What it runs on

identity:
Okta, OpenLDAP, the Okta LDAP agent
access:
Cloudflare Zero Trust, Cloudflare Tunnel
infrastructure:
Terraform, Google Cloud, self-hosted Mac mini
secrets:
1Password, macOS Keychain