Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a3bdc72
feat: add connection profiles support
kushalshit27 Nov 6, 2025
44cd20b
Merge branch 'master' into DXCDT-1281-superfed
kushalshit27 Nov 12, 2025
6722c85
docs: update connection profiles section in resource-specific documen…
kushalshit27 Nov 14, 2025
94d74cf
Merge branch 'master' into DXCDT-1281-superfed
kushalshit27 Nov 14, 2025
e2237b6
Merge branch 'master' into DXCDT-1281-superfed
kushalshit27 Nov 14, 2025
8d1b80f
Merge branch 'master' into DXCDT-1281-superfed
kushalshit27 Nov 19, 2025
8c1cb0f
Merge branch 'master' into DXCDT-1281-superfed
kushalshit27 Nov 19, 2025
85462d7
feat: update connection name prefix template and handle pagination er…
kushalshit27 Nov 20, 2025
f2f9971
feat: add connectionProfiles to YAML context and mockMgmtClient
kushalshit27 Nov 20, 2025
1696c7c
feat: enhance client handling and mapping
kushalshit27 Nov 20, 2025
f99a3b2
feat: update tests for clients and selfServiceProfiles handlers
kushalshit27 Nov 20, 2025
4fb2bdd
feat: update clientGrants and resourceServers handlers
kushalshit27 Nov 20, 2025
f951e26
recordings updated
kushalshit27 Nov 20, 2025
2b044c0
Merge branch 'master' into DXCDT-1281-superfed
kushalshit27 Nov 21, 2025
41546f2
feat(clients.ts): add early return for clients without express config…
kushalshit27 Nov 21, 2025
db45d85
feat(test): add tests for clients and connectionProfiles handling
kushalshit27 Nov 21, 2025
74a532e
feat(docs): update resource-specific documentation for clients
kushalshit27 Nov 21, 2025
2eb298b
feat(clients): add My App with Express Config example
kushalshit27 Nov 21, 2025
ff1e6b5
Merge branch 'master' into DXCDT-1281-superfed
kushalshit27 Nov 21, 2025
e433315
feat(docs): clarify express_configuration usage in connection profile…
kushalshit27 Nov 21, 2025
ea502d1
Merge branch 'DXCDT-1281-superfed' of https://github.com/auth0/auth0-…
kushalshit27 Nov 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions docs/resource-specific-documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -575,3 +575,82 @@ phoneProviders:
}
]
```

## Connection Profiles

Application specific configuration for use with the OIN Express Configuration feature

### YAML Example

```yaml
# Contents of ./tenant.yaml
connectionProfiles:
- name: 'Enterprise SSO Profile'
organization:
show_as_button: 'required'
assign_membership_on_login: 'required'
connection_name_prefix_template: 'org-{organization_name}'
enabled_features:
- scim
- universal_logout
strategy_overrides:
samlp:
enabled_features:
- universal_logout
oidc:
enabled_features:
- scim
- universal_logout
- name: 'Basic Connection Profile'
organization:
show_as_button: 'optional'
assign_membership_on_login: 'optional'
enabled_features:
- scim
```

### Directory Example

File: `./connection-profiles/Enterprise SSO Profile.json`

```json
{
"name": "Enterprise SSO Profile",
"organization": {
"show_as_button": "required",
"assign_membership_on_login": "required"
},
"connection_name_prefix_template": "org-{organization_name}",
"enabled_features": ["scim", "universal_logout"],
"strategy_overrides": {
"samlp": {
"enabled_features": ["universal_logout"]
},
"oidc": {
"enabled_features": ["scim", "universal_logout"]
}
}
}
```

### Express Configuration on Clients

Connection profiles are used in conjunction with the `express_configuration` property on client applications:

```yaml
clients:
- name: 'My Enterprise App'
app_type: 'regular_web'
express_configuration:
initiate_login_uri_template: 'https://myapp.com/sso/start?org={organization_name}&conn={connection_name}'
user_attribute_profile_id: 'My User Attribute Profile'
connection_profile_id: 'Enterprise SSO Profile' # Reference to connection profile
enable_client: true
enable_organization: true
okta_oin_client_id: 'My Okta OIN Client'
admin_login_domain: 'login.myapp.com'
linked_clients:
- client_id: 'client_id_of_mobile_app'
```

For more details, see the [Management API documentation](https://auth0.com/docs/api/management/v2).
13 changes: 13 additions & 0 deletions examples/directory/clients/My Express App.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "My Express App",
"app_type": "regular_web",
"express_configuration": {
"initiate_login_uri_template": "https://myapp.com/sso/start?org={organization_name}&conn={connection_name}",
"user_attribute_profile_id": "My User Attribute Profile",
"connection_profile_id": "Enterprise SSO Profile",
"enable_client": true,
"enable_organization": true,
"okta_oin_client_id": "My Okta OIN Client",
"admin_login_domain": "login.myapp.com"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "Basic Connection Profile",
"organization": {
"show_as_button": "optional",
"assign_membership_on_login": "optional"
},
"enabled_features": [
"scim"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "Enterprise SSO Profile",
"organization": {
"show_as_button": "required",
"assign_membership_on_login": "required"
},
"connection_name_prefix_template": "org-{org_name}",
"enabled_features": [
"scim",
"universal_logout"
],
"strategy_overrides": {
"samlp": {
"enabled_features": [
"universal_logout"
],
"connection_config": {}
},
"oidc": {
"enabled_features": [
"scim",
"universal_logout"
],
"connection_config": {}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "My User Attribute Profile",
"description": "My User Attribute Profile Description",
"user_attributes": [
{
"name": "email",
"description": "Email",
"type": "email",
"required": true
}
]
}
47 changes: 47 additions & 0 deletions examples/yaml/tenant.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ clients:
name: "My Resource Server Client"
app_type: "resource_server"
resource_server_identifier: "https://##ENV##.myapp.com/api/v1"
-
name: "My Okta OIN Client"
app_type: "regular_web"
-
name: "My Express App"
app_type: "regular_web"
express_configuration:
initiate_login_uri_template: "https://myapp.com/sso/start?org={organization_name}&conn={connection_name}"
user_attribute_profile_id: "My User Attribute Profile"
connection_profile_id: "Enterprise SSO Profile"
enable_client: true
enable_organization: true
okta_oin_client_id: "My Okta OIN Client"
admin_login_domain: "login.myapp.com"

databases:
- name: "users"
Expand Down Expand Up @@ -372,3 +386,36 @@ attackProtection:
max_attempts: 50
rate: 1200

connectionProfiles:
- name: "Enterprise SSO Profile"
organization:
show_as_button: "required"
assign_membership_on_login: "required"
connection_name_prefix_template: "org-{org_name}"
enabled_features:
- scim
- universal_logout
strategy_overrides:
samlp:
enabled_features:
- universal_logout
oidc:
enabled_features:
- scim
- universal_logout
- name: "Basic Connection Profile"
organization:
show_as_button: "optional"
assign_membership_on_login: "optional"
enabled_features:
- scim

userAttributeProfiles:
- name: "My User Attribute Profile"
description: "My User Attribute Profile Description"
user_attributes:
- name: "email"
description: "Email"
type: "email"
required: true

14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"homepage": "https://github.com/auth0/auth0-deploy-cli#readme",
"dependencies": {
"ajv": "^6.12.6",
"auth0": "^4.36.0",
"auth0": "^4.37.0",
"dot-prop": "^5.3.0",
"fs-extra": "^10.1.0",
"js-yaml": "^4.1.1",
Expand Down
35 changes: 35 additions & 0 deletions src/context/directory/handlers/clients.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ function parse(context: DirectoryContext): ParsedClients {

async function dump(context: DirectoryContext): Promise<void> {
const { clients } = context.assets;
const { userAttributeProfiles, connectionProfiles } = context.assets;

if (!clients) return; // Skip, nothing to dump

Expand All @@ -73,6 +74,40 @@ async function dump(context: DirectoryContext): Promise<void> {

client.custom_login_page = `./${clientName}_custom_login_page.html`;
}

if (client.express_configuration) {
// map ids to names for user attribute profiles
const userAttributeProfileId = client?.express_configuration?.user_attribute_profile_id;
if (client.express_configuration && userAttributeProfileId) {
const p = userAttributeProfiles?.find((uap) => uap.id === userAttributeProfileId);
client.express_configuration.user_attribute_profile_id = p?.name || userAttributeProfileId;
}

// map ids to names for connection profiles
const connectionProfilesProfileId = client?.express_configuration?.connection_profile_id;
if (client.express_configuration && connectionProfilesProfileId) {
const c = connectionProfiles?.find((uap) => uap.id === connectionProfilesProfileId);
client.express_configuration.connection_profile_id = c?.name || connectionProfilesProfileId;
}

// map ids to names for okta oin clients
const oktaOinClientId = client?.express_configuration?.okta_oin_client_id;
if (client.express_configuration && oktaOinClientId) {
const o = clients?.find((uap) => uap.client_id === oktaOinClientId);
client.express_configuration.okta_oin_client_id = o?.name || oktaOinClientId;
}
}

if (client.app_type === 'express_configuration') {
// only keep relevant fields for express configuration
client = {
name: client.name,
app_type: client.app_type,
client_authentication_methods: client.client_authentication_methods,
organization_require_behavior: client.organization_require_behavior,
} as Client;
}

dumpJSON(clientFile, clearClientArrays(client));
});
}
Expand Down
65 changes: 65 additions & 0 deletions src/context/directory/handlers/connectionProfiles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import path from 'path';
import fs from 'fs-extra';
import { ConnectionProfile } from 'auth0';
import { constants } from '../../../tools';
import log from '../../../logger';

import { dumpJSON, existsMustBeDir, getFiles, loadJSON, sanitize } from '../../../utils';
import DirectoryContext from '..';
import { ParsedAsset } from '../../../types';

type ParsedConnectionProfiles = ParsedAsset<'connectionProfiles', Partial<ConnectionProfile>[]>;

function parse(context: DirectoryContext): ParsedConnectionProfiles {
const connectionProfilesFolder = path.join(
context.filePath,
constants.CONNECTION_PROFILES_DIRECTORY
);
if (!existsMustBeDir(connectionProfilesFolder)) return { connectionProfiles: null }; // Skip

const files = getFiles(connectionProfilesFolder, ['.json']);

const connectionProfiles = files.map((f) => {
const profile = {
...loadJSON(f, {
mappings: context.mappings,
disableKeywordReplacement: context.disableKeywordReplacement,
}),
};
return profile;
});

return {
connectionProfiles,
};
}

async function dump(context: DirectoryContext): Promise<void> {
const { connectionProfiles } = context.assets;
if (!connectionProfiles) return;

const connectionProfilesFolder = path.join(
context.filePath,
constants.CONNECTION_PROFILES_DIRECTORY
);
fs.ensureDirSync(connectionProfilesFolder);

connectionProfiles.forEach((profile) => {
const profileFile = path.join(connectionProfilesFolder, sanitize(`${profile.name}.json`));
log.info(`Writing ${profileFile}`);

// Remove read-only fields
if ('id' in profile) {
delete profile.id;
}

dumpJSON(profileFile, profile);
});
}

const connectionProfilesHandler = {
parse,
dump,
};

export default connectionProfilesHandler;
2 changes: 2 additions & 0 deletions src/context/directory/handlers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import flows from './flows';
import flowVaultConnections from './flowVaultConnections';
import networkACLs from './networkACLs';
import userAttributeProfiles from './userAttributeProfiles';
import connectionProfiles from './connectionProfiles';

import DirectoryContext from '..';
import { AssetTypes, Asset } from '../../../types';
Expand Down Expand Up @@ -80,6 +81,7 @@ const directoryHandlers: {
selfServiceProfiles,
networkACLs,
userAttributeProfiles,
connectionProfiles,
};

export default directoryHandlers;
Loading