Skip to content

Commit 2b2e3c1

Browse files
committed
fix(blog): correct identity stack examples
1 parent d2a12cb commit 2b2e3c1

1 file changed

Lines changed: 20 additions & 12 deletions

File tree

  • content/blog/identity-stack-cookbook-auth0-okta-azuread-keycloak

content/blog/identity-stack-cookbook-auth0-okta-azuread-keycloak/index.md

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ social:
2727

2828
Managing identity at scale requires more than a login box. Platform teams need consistent application access patterns across Auth0, Okta, Microsoft Entra ID, and Keycloak.
2929

30-
In this cookbook, we'll explore how to implement a portable identity pattern using Pulumi. We'll cover Auth0, Okta, Microsoft Entra ID, and Keycloak, focusing on a common requirement: one application and one access group.
30+
In this cookbook, we'll explore how to implement a portable identity pattern using Pulumi. We'll cover Auth0, Okta, Microsoft Entra ID, and Keycloak, focusing on a common requirement: one application and one provider-specific access container.
3131

3232
This post provides a common SSO application pattern across these providers for your own applications, rather than configuring Pulumi organization SSO. By the end, you will have implemented a portable identity pattern across Auth0, Okta, Microsoft Entra ID, and Keycloak.
3333

@@ -47,13 +47,13 @@ Identity providers (IdPs) are often treated as static infrastructure, but they a
4747
The goal is to create a reusable pattern that works across different providers. This pattern includes:
4848

4949
1. **An application**: The service or platform users will access.
50-
1. **A group**: A collection of users who should have access to the application.
50+
1. **An access container**: A provider-specific organization, group, or role assignment that controls who should have access to the application.
5151

5252
## Auth0
5353

54-
Auth0 is known for its developer-friendly approach and extensibility. While Auth0 handles SCIM through Enterprise Connections or Actions, the core setup involves defining a client and a connection.
54+
Auth0 is known for its developer-friendly approach and extensibility. Auth0 does not model application access as a generic group assignment. A practical baseline is to define an application client that requires organization login, an organization as the access boundary, and a connection enabled for that client.
5555

56-
Prerequisites: an Auth0 tenant, a Machine-to-Machine application with Management API scopes for clients, organizations, and connections, and the Pulumi Auth0 provider configured with the tenant domain, client ID, and client secret.
56+
Prerequisites: an Auth0 tenant, a Machine-to-Machine application with Management API scopes for clients, organizations, connections, and connection clients, and the Pulumi Auth0 provider configured with the tenant domain, client ID, and client secret.
5757

5858
```typescript
5959
import * as auth0 from "@pulumi/auth0";
@@ -62,16 +62,22 @@ const client = new auth0.Client("auth0-app", {
6262
name: "My Application",
6363
appType: "regular_web",
6464
callbacks: ["https://myapp.com/callback"],
65+
organizationUsage: "require",
66+
organizationRequireBehavior: "pre_login_prompt",
6567
});
6668

67-
const organization = new auth0.Organization("auth0-group", {
68-
name: "my-group",
69-
displayName: "My Group",
69+
const organization = new auth0.Organization("auth0-organization", {
70+
name: "my-organization",
71+
displayName: "My Organization",
7072
});
7173

7274
const connection = new auth0.Connection("auth0-connection", {
7375
name: "my-connection",
7476
strategy: "auth0",
77+
});
78+
79+
const connectionClients = new auth0.ConnectionClients("auth0-connection-clients", {
80+
connectionId: connection.id,
7581
enabledClients: [client.clientId],
7682
});
7783

@@ -111,10 +117,12 @@ const assignment = new okta.app.GroupAssignment("okta-assignment", {
111117

112118
## Microsoft Entra ID
113119

114-
For organizations heavily invested in the Microsoft ecosystem, Microsoft Entra ID is the standard. Pulumi allows you to manage applications and service principals with ease.
120+
For organizations heavily invested in the Microsoft ecosystem, Microsoft Entra ID is the standard. Pulumi allows you to manage applications and service principals with ease. This minimal example focuses on the application, service principal, group, and assignment resources; add redirect URI and platform configuration for your specific application type before using it as a live SSO app.
115121

116122
Prerequisites: a Microsoft Entra tenant, permissions to create applications, service principals, groups, and app role assignments, and the Pulumi Microsoft Entra ID provider authenticated through your chosen Azure identity flow.
117123

124+
The default app role ID assigns the group to the application without requiring a custom app role. Replace it with an `appRoles[].id` value when your application defines custom roles.
125+
118126
```typescript
119127
import * as azuread from "@pulumi/azuread";
120128

@@ -127,15 +135,14 @@ const group = new azuread.Group("entra-group", {
127135
displayName: "My Group",
128136
mailEnabled: false,
129137
securityEnabled: true,
130-
types: ["Unified"],
131138
});
132139

133140
const servicePrincipal = new azuread.ServicePrincipal("entra-sp", {
134141
clientId: app.clientId,
135142
});
136143

137144
const assignment = new azuread.AppRoleAssignment("entra-assignment", {
138-
appRoleId: "00000000-0000-0000-0000-000000000000", // Default access role; replace with an appRoles[].id for custom roles.
145+
appRoleId: "00000000-0000-0000-0000-000000000000",
139146
principalObjectId: group.objectId,
140147
resourceObjectId: servicePrincipal.objectId,
141148
});
@@ -169,7 +176,7 @@ const group = new keycloak.Group("keycloak-group", {
169176
name: "My Group",
170177
});
171178

172-
const role = new keycloak.openid.ClientRole("keycloak-app-user-role", {
179+
const role = new keycloak.Role("keycloak-app-user-role", {
173180
realmId: realm.id,
174181
clientId: client.id,
175182
name: "app-user",
@@ -179,11 +186,12 @@ const groupRoles = new keycloak.GroupRoles("keycloak-group-roles", {
179186
realmId: realm.id,
180187
groupId: group.id,
181188
roleIds: [role.id],
189+
exhaustive: false,
182190
});
183191
```
184192

185193
## When to switch and how
186194

187195
Choosing an identity provider depends on your specific needs. Auth0 is a strong fit for external application authentication. Okta and Microsoft Entra ID are common choices for internal workforce management. Keycloak is ideal for teams that need full control over their identity infrastructure.
188196

189-
When switching providers, the key is to maintain the same logical structure. By using Pulumi, you can swap the provider-specific resources while keeping your application logic intact. This approach ensures that your identity stack remains as portable as your cloud infrastructure.
197+
When switching providers, the key is to maintain the same logical structure. By using Pulumi, you can keep the same intent in code while mapping it to each provider's resource model. Auth0 organizations, Okta groups, Entra ID groups, and Keycloak groups are not identical, so migrations still require a provider-specific access review.

0 commit comments

Comments
 (0)