Saltar al contenido principal

Automatiza la gestión de tenants

Puedes gestionar los tenants de Logto Cloud de forma programática, incluyendo la creación de tenants y la continuación de la configuración sin cambiar a la Consola.

Esto es útil cuando necesitas aprovisionar tenants desde tu propio flujo de onboarding, plataforma interna, agente de IA o automatización de integraciones.

El flujo de automatización es:

  1. Usa un Logto Cloud Personal Access Token (PAT) para llamar a la API de Logto Cloud.
  2. Crea un tenant con POST /api/tenants.
  3. Lee las credenciales predeterminadas de la aplicación máquina a máquina (M2M) de la respuesta de creación.
  4. Usa la aplicación M2M predeterminada para obtener un token de acceso de la Management API para el nuevo tenant.
  5. Llama a la Management API del nuevo tenant para continuar aprovisionando aplicaciones, usuarios, roles, recursos, organizaciones y otros ajustes.

Antes de comenzar

Prepara los siguientes valores:

VariableDescripción
CLOUD_API_ENDPOINTEl endpoint de la API de Logto Cloud. Para Logto Cloud, usa https://cloud.logto.io.
LOGTO_CLOUD_PATUn PAT para tu cuenta de Logto Cloud.
TENANT_NAMEEl nombre visible del tenant a crear.
TENANT_TAGEl tipo de tenant. Usa development o production.
REGION_NAMEEl identificador de la región para el tenant.

Establécelos como variables de entorno:

export CLOUD_API_ENDPOINT="https://cloud.logto.io"
export LOGTO_CLOUD_PAT="<logto-cloud-pat>"
export TENANT_NAME="Mi tenant automatizado"
export TENANT_TAG="development"
export REGION_NAME="<region-name>"

Obtener regiones disponibles

Antes de crear un tenant, obtén las regiones disponibles para tu cuenta de Logto Cloud:

curl "$CLOUD_API_ENDPOINT/api/me/regions" \
-H "Authorization: Bearer $LOGTO_CLOUD_PAT"

La respuesta contiene las regiones disponibles. Usa el valor name como REGION_NAME al crear el tenant.

Ejemplo de respuesta:

{
"regions": [
{
"name": "EU",
"displayName": "Europe"
},
{
"name": "US",
"displayName": "United States"
}
]
}

Crear un tenant

Llama a POST /api/tenants con el Logto Cloud PAT:

curl "$CLOUD_API_ENDPOINT/api/tenants" \
-X POST \
-H "Authorization: Bearer $LOGTO_CLOUD_PAT" \
-H "Content-Type: application/json" \
-d '{
"name": "'"$TENANT_NAME"'",
"tag": "'"$TENANT_TAG"'",
"regionName": "'"$REGION_NAME"'"
}'

La respuesta incluye el tenant creado y una aplicación M2M predeterminada. La aplicación M2M se crea en el nuevo tenant y tiene acceso a la Management API del tenant.

Ejemplo de respuesta:

{
"id": "new-tenant-id",
"name": "Mi tenant automatizado",
"tag": "development",
"indicator": "https://new-tenant-id.logto.app",
"regionName": "EU",
"defaultApplication": {
"id": "default-m2m-app-id",
"secret": "default-m2m-app-secret"
}
}

Guarda los valores que necesitas para el siguiente paso:

export TENANT_ID="<response.id>"
export TENANT_ENDPOINT="<response.indicator>"
export DEFAULT_M2M_APP_ID="<response.defaultApplication.id>"
export DEFAULT_M2M_APP_SECRET="<response.defaultApplication.secret>"

Obtener un token de acceso de la Management API para el nuevo tenant

Usa las credenciales de la aplicación M2M predeterminada para solicitar un token de acceso del nuevo tenant:

curl "$TENANT_ENDPOINT/oidc/token" \
-X POST \
-u "$DEFAULT_M2M_APP_ID:$DEFAULT_M2M_APP_SECRET" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "resource=$TENANT_ENDPOINT/api" \
-d "scope=all"

Ejemplo de respuesta:

{
"access_token": "eyJ...",
"expires_in": 3600,
"token_type": "Bearer",
"scope": "all"
}

Guarda el token de acceso:

export MANAGEMENT_API_ACCESS_TOKEN="<response.access_token>"

Continuar aprovisionando el nuevo tenant

Usa el token de acceso de la Management API para llamar a la Management API del nuevo tenant.

Por ejemplo, listar aplicaciones:

curl "$TENANT_ENDPOINT/api/applications" \
-H "Authorization: Bearer $MANAGEMENT_API_ACCESS_TOKEN"

O crear una aplicación:

curl "$TENANT_ENDPOINT/api/applications" \
-X POST \
-H "Authorization: Bearer $MANAGEMENT_API_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Mi aplicación web",
"type": "SPA",
"oidcClientMetadata": {
"redirectUris": ["https://example.com/callback"],
"postLogoutRedirectUris": ["https://example.com"]
}
}'

En este punto, tu automatización puede continuar con cualquier operación de la Management API, como crear usuarios, aplicaciones, recursos de API, roles, organizaciones, conectores o ajustes de experiencia de inicio de sesión.

Ejemplo de automatización completa

El siguiente ejemplo en Node.js crea un tenant, intercambia las credenciales M2M predeterminadas devueltas por un token de acceso de la Management API y lista las aplicaciones en el nuevo tenant:

const cloudApiEndpoint = 'https://cloud.logto.io';
const logtoCloudPat = process.env.LOGTO_CLOUD_PAT;

const createTenantResponse = await fetch(`${cloudApiEndpoint}/api/tenants`, {
method: 'POST',
headers: {
authorization: `Bearer ${logtoCloudPat}`,
'content-type': 'application/json',
},
body: JSON.stringify({
name: 'Mi tenant automatizado',
tag: 'development',
regionName: 'EU',
}),
});

if (!createTenantResponse.ok) {
throw new Error(`Error al crear el tenant: ${await createTenantResponse.text()}`);
}

const tenant = await createTenantResponse.json();
const tenantEndpoint = tenant.indicator;
const { id: appId, secret: appSecret } = tenant.defaultApplication;

const tokenResponse = await fetch(`${tenantEndpoint}/oidc/token`, {
method: 'POST',
headers: {
authorization: `Basic ${Buffer.from(`${appId}:${appSecret}`).toString('base64')}`,
'content-type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
grant_type: 'client_credentials',
resource: `${tenantEndpoint}/api`,
scope: 'all',
}),
});

if (!tokenResponse.ok) {
throw new Error(`Error al obtener el token de la Management API: ${await tokenResponse.text()}`);
}

const { access_token: managementApiAccessToken } = await tokenResponse.json();

const applicationsResponse = await fetch(`${tenantEndpoint}/api/applications`, {
headers: {
authorization: `Bearer ${managementApiAccessToken}`,
},
});

if (!applicationsResponse.ok) {
throw new Error(`Error al listar aplicaciones: ${await applicationsResponse.text()}`);
}

const applications = await applicationsResponse.json();

console.log({ tenantId: tenant.id, applications });