diff --git a/public/api/scalekit.scalar.json b/public/api/scalekit.scalar.json index f1fe42c45..7a4f7c6e5 100644 --- a/public/api/scalekit.scalar.json +++ b/public/api/scalekit.scalar.json @@ -228,6 +228,60 @@ } } }, + "/api/v1/connected_accounts/-:disconnect": { + "post": { + "description": "Disconnects a connected account by setting its status to DISCONNECTED. The account record is retained but is marked as no longer active.", + "tags": ["Connected Accounts"], + "summary": "Disconnect a connected account", + "operationId": "ConnectedAccountService_DisconnectConnectedAccount2", + "responses": { + "200": { + "description": "Successfully disconnected the connected account", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connected_accountsDisconnectConnectedAccountResponse" + } + } + } + }, + "400": { + "description": "Invalid request - missing or malformed connected account ID", + "content": { + "application/json": { + "schema": {} + } + } + }, + "401": { + "description": "Authentication required - missing or invalid access token", + "content": { + "application/json": { + "schema": {} + } + } + }, + "404": { + "description": "Connected account not found", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connected_accountsDisconnectConnectedAccountRequest" + } + } + }, + "required": true + } + } + }, "/api/v1/connected_accounts/auth": { "get": { "description": "Retrieves complete authentication details for a connected account including OAuth tokens, refresh tokens, scopes, and API configuration. Query by account ID or by combination of organization/user, connector, and identifier. Returns sensitive credential information - use appropriate access controls.", @@ -314,6 +368,92 @@ } } }, + "/api/v1/connected_accounts/details": { + "get": { + "description": "Returns metadata for a connected account including status, connector type, provider, and configuration without exposing stored authorization credentials. Look up by account ID, or by a combination of organization (or user), connector, and external identifier.", + "tags": ["Connected Accounts"], + "summary": "Get connected account details", + "operationId": "ConnectedAccountService_GetConnectedAccountDetails", + "parameters": [ + { + "schema": { + "type": "string" + }, + "description": "Organization ID for the connector", + "name": "organization_id", + "in": "query" + }, + { + "schema": { + "type": "string" + }, + "description": "User ID for the connector", + "name": "user_id", + "in": "query" + }, + { + "schema": { + "type": "string" + }, + "description": "Connector identifier", + "name": "connector", + "in": "query" + }, + { + "schema": { + "type": "string" + }, + "description": "The unique identifier for the connected account within the third-party service (e.g., email address, user ID, workspace identifier).", + "name": "identifier", + "in": "query" + }, + { + "schema": { + "type": "string" + }, + "description": "Unique identifier for the connected account", + "name": "id", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successfully retrieved connected account details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connected_accountsGetConnectedAccountByIdentifierResponse" + } + } + } + }, + "400": { + "description": "Invalid request - missing required query parameters", + "content": { + "application/json": { + "schema": {} + } + } + }, + "401": { + "description": "Authentication required - missing or invalid access token", + "content": { + "application/json": { + "schema": {} + } + } + }, + "404": { + "description": "Connected account not found - no account matches the specified criteria", + "content": { + "application/json": { + "schema": {} + } + } + } + } + } + }, "/api/v1/connected_accounts/magic_link": { "post": { "description": "Creates a time-limited magic link for connecting or re-authorizing a third-party account. The link directs users to the OAuth authorization flow for the specified connector. Returns the generated link URL and expiration timestamp. Links typically expire after a short duration for security.", @@ -360,6 +500,60 @@ } } }, + "/api/v1/connected_accounts/this": { + "get": { + "description": "Retrieves a connected account by its unique ID. Use the path '/this' (e.g. /api/v1/connected_accounts/this) to retrieve the connected account associated with the current token context.", + "tags": ["Connected Accounts"], + "summary": "Get a connected account", + "operationId": "ConnectedAccountService_GetConnectedAccount", + "parameters": [ + { + "schema": { + "type": "string" + }, + "description": "Unique identifier for the connected account. Always prefixed with 'ca_'. If omitted (via the /this path), the connected account is resolved from the current token context.", + "name": "id", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successfully retrieved the connected account", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connected_accountsGetConnectedAccountResponse" + } + } + } + }, + "400": { + "description": "Invalid request - missing or malformed connected account ID", + "content": { + "application/json": { + "schema": {} + } + } + }, + "401": { + "description": "Authentication required - missing or invalid access token", + "content": { + "application/json": { + "schema": {} + } + } + }, + "404": { + "description": "Connected account not found", + "content": { + "application/json": { + "schema": {} + } + } + } + } + } + }, "/api/v1/connected_accounts/user/verify": { "post": { "description": "Confirms the user assertion and activates the connected account after the user completes third-party OAuth. Called by the B2B app server with auth_request_id and identifier. Validates that the asserted identifier matches the one stored on the auth request and promotes pending tokens to live.", @@ -422,6 +616,126 @@ } } }, + "/api/v1/connected_accounts/{id}": { + "get": { + "description": "Retrieves a connected account by its unique ID. Use the path '/this' (e.g. /api/v1/connected_accounts/this) to retrieve the connected account associated with the current token context.", + "tags": ["Connected Accounts"], + "summary": "Get a connected account", + "operationId": "ConnectedAccountService_GetConnectedAccount2", + "parameters": [ + { + "schema": { + "type": "string" + }, + "description": "Unique identifier for the connected account. Always prefixed with 'ca_'. If omitted (via the /this path), the connected account is resolved from the current token context.", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Successfully retrieved the connected account", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connected_accountsGetConnectedAccountResponse" + } + } + } + }, + "400": { + "description": "Invalid request - missing or malformed connected account ID", + "content": { + "application/json": { + "schema": {} + } + } + }, + "401": { + "description": "Authentication required - missing or invalid access token", + "content": { + "application/json": { + "schema": {} + } + } + }, + "404": { + "description": "Connected account not found", + "content": { + "application/json": { + "schema": {} + } + } + } + } + } + }, + "/api/v1/connected_accounts/{id}:disconnect": { + "post": { + "description": "Disconnects a connected account by setting its status to DISCONNECTED. The account record is retained but is marked as no longer active.", + "tags": ["Connected Accounts"], + "summary": "Disconnect a connected account", + "operationId": "ConnectedAccountService_DisconnectConnectedAccount", + "parameters": [ + { + "schema": { + "type": "string" + }, + "description": "Unique identifier for the connected account to disconnect. Always prefixed with 'ca_'.", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Successfully disconnected the connected account", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/connected_accountsDisconnectConnectedAccountResponse" + } + } + } + }, + "400": { + "description": "Invalid request - missing or malformed connected account ID", + "content": { + "application/json": { + "schema": {} + } + } + }, + "401": { + "description": "Authentication required - missing or invalid access token", + "content": { + "application/json": { + "schema": {} + } + } + }, + "404": { + "description": "Connected account not found", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConnectedAccountServiceDisconnectConnectedAccountBody" + } + } + }, + "required": true + } + } + }, "/api/v1/connected_accounts:delete": { "post": { "description": "Permanently removes a connected account and revokes all associated authentication credentials. Identify the account by ID, or by combination of organization/user, connector, and identifier. This action cannot be undone. All OAuth tokens and API keys for this account will be invalidated.", @@ -836,6 +1150,7 @@ "application/json": { "schema": { "description": "Membership details to create. Required fields must be provided.", + "required": ["membership"], "$ref": "#/components/schemas/v1usersCreateMembership" } } @@ -1746,6 +2061,66 @@ ] } }, + "/api/v1/organizations/{org_id}/roles/{role_name}/base": { + "delete": { + "description": "Removes the base role inheritance relationship for a specified organization role, effectively eliminating all inherited permissions from the base role. Use this endpoint when you want to break the hierarchical relationship between roles and remove inherited permissions within the organization. The role will retain only its directly assigned permissions after this operation. This action cannot be undone, so ensure the role has sufficient direct permissions before removing inheritance.", + "tags": ["Roles"], + "summary": "Remove organization role inheritance", + "operationId": "RolesService_DeleteOrganizationRoleBase", + "parameters": [ + { + "schema": { + "type": "string" + }, + "description": "Unique identifier to an Organization", + "name": "org_id", + "in": "path", + "required": true + }, + { + "schema": { + "type": "string" + }, + "description": "Name of the organization role to remove base from", + "name": "role_name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Organization role base inheritance relationship successfully removed. The role now has only its directly assigned permissions.", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "x-codeSamples": [ + { + "label": "Node.js SDK", + "lang": "javascript", + "source": "await scalekit.role.deleteOrganizationRoleBase(\"org_123\", \"senior_editor\");" + }, + { + "label": "Python SDK", + "lang": "python", + "source": "scalekit_client.roles.delete_organization_role_base(\n org_id=\"org_123\",\n role_name=\"senior_editor\"\n)" + }, + { + "label": "Go SDK", + "lang": "go", + "source": "err := scalekitClient.Role().DeleteOrganizationRoleBase(ctx, \"org_123\", \"senior_editor\")\nif err != nil {\n // handle error\n}" + }, + { + "label": "Java SDK", + "lang": "java", + "source": "scalekitClient.roles().deleteOrganizationRoleBase(\"org_123\", \"senior_editor\");" + } + ] + } + }, "/api/v1/organizations/{org_id}/roles:set_defaults": { "patch": { "description": "Updates the default member role for the specified organization. Use this endpoint to configure which role is automatically assigned to new users when they join the organization. The system will validate that the specified role exists and update the organization settings accordingly. This configuration affects all new user invitations and memberships within the organization.", @@ -3004,99 +3379,219 @@ } } }, - "required": true - } + "required": true + } + } + }, + "/api/v1/organizations/{organization_id}/domains/{id}": { + "get": { + "description": "Retrieves complete details for a domain including domain type, timestamps, and configuration information.\n\n", + "tags": ["Domains"], + "summary": "Get Domain", + "operationId": "DomainService_GetDomain", + "parameters": [ + { + "schema": { + "type": "string" + }, + "description": "Scalekit-generated unique identifier for the organization. Use either this or external_id to identify the organization.", + "name": "organization_id", + "in": "path", + "required": true + }, + { + "schema": { + "type": "string" + }, + "description": "Scalekit-generated unique identifier of the domain to retrieve.", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Successfully retrieved the domain details.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/domainsGetDomainResponse" + } + } + } + } + }, + "x-codeSamples": [ + { + "label": "Node.js SDK", + "lang": "javascript", + "source": "// Fetch details of a specific domain\nconst response = await scalekit.domain.getDomain(organizationId, domainId);\n\n// Domain object properties:\n// - id: Domain identifier\n// - domain: Domain name\n// - organizationId: Owning organization\n// - domainType: Domain configuration type" + }, + { + "label": "Python SDK", + "lang": "python", + "source": "# Fetch details of a specific domain\nresponse = scalekit_client.domain.get_domain(organization_id=\"org_123\", domain_id=\"dom_123\")" + }, + { + "label": "Go SDK", + "lang": "go", + "source": "domain, err := scalekitClient.Domain().GetDomain(ctx, \"dom_123\", \"org_123\")" + }, + { + "label": "Java SDK", + "lang": "java", + "source": "Domain domain = scalekitClient.domains().getDomainById(\"org_123\", \"dom_123\");" + } + ] + }, + "delete": { + "description": "Permanently removes a domain record from an organization.\n\n- Deleting an ORGANIZATION_DOMAIN disables SSO routing/enforcement for that domain.\n- Deleting an ALLOWED_EMAIL_DOMAIN stops organization suggestions for users with that email domain.\n\n", + "tags": ["Domains"], + "summary": "Delete Domain", + "operationId": "DomainService_DeleteDomain", + "parameters": [ + { + "schema": { + "type": "string" + }, + "description": "Scalekit-generated unique identifier for the organization. Use either this or external_id to identify the organization.", + "name": "organization_id", + "in": "path", + "required": true + }, + { + "schema": { + "type": "string" + }, + "description": "Scalekit-generated unique identifier of the domain to be permanently deleted.", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Domain successfully deleted.", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "x-codeSamples": [ + { + "label": "Node.js SDK", + "lang": "javascript", + "source": "// Remove a domain from an organization\n// Caution: Deletion is permanent and may affect user access\nconst response = await scalekit.domain.deleteDomain(organizationId, domainId);" + }, + { + "label": "Python SDK", + "lang": "python", + "source": "# Remove a domain from an organization\n# Caution: Deletion is permanent and may affect user access\nresponse = scalekit_client.domain.delete_domain(\n organization_id=\"org_123\",\n domain_id=\"dom_123\"\n)" + }, + { + "label": "Go SDK", + "lang": "go", + "source": "err = scalekitClient.Domain().DeleteDomain(ctx, \"dom_123\", \"org_123\")" + }, + { + "label": "Java SDK", + "lang": "java", + "source": "scalekitClient.domains().deleteDomain(organization.getId(), domain.getId());" + } + ] } }, - "/api/v1/organizations/{organization_id}/domains/{id}": { + "/api/v1/organizations/{organization_id}/session-policy": { "get": { - "description": "Retrieves complete details for a domain including domain type, timestamps, and configuration information.\n\n", - "tags": ["Domains"], - "summary": "Get Domain", - "operationId": "DomainService_GetDomain", + "description": "Retrieves the session policy for an organization. Returns session_policy='APPLICATION' if the organization inherits the application-level defaults, or session_policy='CUSTOM' with the configured values if a custom policy is active.", + "tags": ["Organizations"], + "summary": "Get organization session policy", + "operationId": "OrganizationService_GetOrganizationSessionPolicy", "parameters": [ { "schema": { "type": "string" }, - "description": "Scalekit-generated unique identifier for the organization. Use either this or external_id to identify the organization.", + "description": "The unique identifier of the organization whose session policy is being requested.", "name": "organization_id", "in": "path", "required": true - }, - { - "schema": { - "type": "string" - }, - "description": "Scalekit-generated unique identifier of the domain to retrieve.", - "name": "id", - "in": "path", - "required": true } ], "responses": { "200": { - "description": "Successfully retrieved the domain details.", + "description": "Session policy retrieved successfully.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/domainsGetDomainResponse" + "$ref": "#/components/schemas/organizationsGetOrganizationSessionPolicyResponse" } } } + }, + "404": { + "description": "Organization not found.", + "content": { + "application/json": { + "schema": {} + } + } } }, "x-codeSamples": [ { "label": "Node.js SDK", "lang": "javascript", - "source": "// Fetch details of a specific domain\nconst response = await scalekit.domain.getDomain(organizationId, domainId);\n\n// Domain object properties:\n// - id: Domain identifier\n// - domain: Domain name\n// - organizationId: Owning organization\n// - domainType: Domain configuration type" + "source": "const policy = await scalekit.organization.getOrganizationSessionPolicy('');\n\nconsole.log('Policy source:', policy.policySource);\nconsole.log('Absolute timeout (minutes):', policy.absoluteSessionTimeout);\nconsole.log('Idle timeout enabled:', policy.idleSessionTimeoutEnabled);" }, { "label": "Python SDK", "lang": "python", - "source": "# Fetch details of a specific domain\nresponse = scalekit_client.domain.get_domain(organization_id=\"org_123\", domain_id=\"dom_123\")" + "source": "from scalekit.v1.organizations.organizations_pb2 import SessionPolicyType\n\nresponse, _ = scalekit_client.organization.get_organization_session_policy('')\npolicy = response.policy\n\nif policy.policy_source == SessionPolicyType.CUSTOM:\n print('Absolute timeout (minutes):', policy.absolute_session_timeout.value)\n print('Idle timeout enabled:', policy.idle_session_timeout_enabled.value)" }, { "label": "Go SDK", "lang": "go", - "source": "domain, err := scalekitClient.Domain().GetDomain(ctx, \"dom_123\", \"org_123\")" + "source": "policy, err := scalekitClient.Organization().GetOrganizationSessionPolicy(ctx, \"\")\nif err != nil {\n log.Fatal(err)\n}\n\nif policy.PolicySource == scalekit.SessionPolicySourceCustom {\n fmt.Println(\"Absolute timeout (minutes):\", policy.AbsoluteSessionTimeout.GetValue())\n fmt.Println(\"Idle timeout enabled:\", policy.IdleSessionTimeoutEnabled.GetValue())\n}" }, { "label": "Java SDK", "lang": "java", - "source": "Domain domain = scalekitClient.domains().getDomainById(\"org_123\", \"dom_123\");" + "source": "import com.scalekit.grpc.scalekit.v1.organizations.OrganizationSessionPolicySettings;\nimport com.scalekit.grpc.scalekit.v1.organizations.SessionPolicyType;\n\nOrganizationSessionPolicySettings policy =\n scalekitClient.organizations().getOrganizationSessionPolicy(\"\");\n\nif (policy.getPolicySource() == SessionPolicyType.CUSTOM) {\n System.out.println(\"Absolute timeout (minutes): \" + policy.getAbsoluteSessionTimeout().getValue());\n System.out.println(\"Idle timeout enabled: \" + policy.getIdleSessionTimeoutEnabled().getValue());\n}" } ] }, - "delete": { - "description": "Permanently removes a domain record from an organization.\n\n- Deleting an ORGANIZATION_DOMAIN disables SSO routing/enforcement for that domain.\n- Deleting an ALLOWED_EMAIL_DOMAIN stops organization suggestions for users with that email domain.\n\n", - "tags": ["Domains"], - "summary": "Delete Domain", - "operationId": "DomainService_DeleteDomain", + "patch": { + "description": "Sets a custom session policy for an organization or reverts to application-level settings. Send session_policy='APPLICATION' to revert to application defaults. Send session_policy='CUSTOM' with timeout values to activate a custom policy.", + "tags": ["Organizations"], + "summary": "Update organization session policy", + "operationId": "OrganizationService_UpdateOrganizationSessionPolicy", "parameters": [ { "schema": { "type": "string" }, - "description": "Scalekit-generated unique identifier for the organization. Use either this or external_id to identify the organization.", + "description": "The unique identifier of the organization whose session policy is being updated.", "name": "organization_id", "in": "path", "required": true - }, - { - "schema": { - "type": "string" - }, - "description": "Scalekit-generated unique identifier of the domain to be permanently deleted.", - "name": "id", - "in": "path", - "required": true } ], "responses": { "200": { - "description": "Domain successfully deleted.", + "description": "Session policy updated successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/organizationsUpdateOrganizationSessionPolicyResponse" + } + } + } + }, + "404": { + "description": "Organization not found.", "content": { "application/json": { "schema": {} @@ -3108,24 +3603,34 @@ { "label": "Node.js SDK", "lang": "javascript", - "source": "// Remove a domain from an organization\n// Caution: Deletion is permanent and may affect user access\nconst response = await scalekit.domain.deleteDomain(organizationId, domainId);" + "source": "// Set a custom policy\nconst updated = await scalekit.organization.updateOrganizationSessionPolicy('', {\n policySource: 'CUSTOM',\n absoluteSessionTimeout: 480,\n absoluteSessionTimeoutUnit: 'MINUTES',\n idleSessionTimeoutEnabled: true,\n idleSessionTimeout: 60,\n idleSessionTimeoutUnit: 'MINUTES',\n});\n\n// Revert to application defaults\nawait scalekit.organization.updateOrganizationSessionPolicy('', {\n policySource: 'APPLICATION',\n});" }, { "label": "Python SDK", "lang": "python", - "source": "# Remove a domain from an organization\n# Caution: Deletion is permanent and may affect user access\nresponse = scalekit_client.domain.delete_domain(\n organization_id=\"org_123\",\n domain_id=\"dom_123\"\n)" + "source": "from scalekit.v1.organizations.organizations_pb2 import SessionPolicyType\nfrom scalekit.v1.commons.commons_pb2 import TimeUnit\n\n# Set a custom policy\nresponse, _ = scalekit_client.organization.update_organization_session_policy(\n organization_id='',\n policy_source=SessionPolicyType.CUSTOM,\n absolute_session_timeout=480,\n absolute_session_timeout_unit=TimeUnit.MINUTES,\n idle_session_timeout_enabled=True,\n idle_session_timeout=60,\n idle_session_timeout_unit=TimeUnit.MINUTES,\n)\n\n# Revert to application defaults\nscalekit_client.organization.update_organization_session_policy(\n organization_id='',\n policy_source=SessionPolicyType.APPLICATION,\n)" }, { "label": "Go SDK", "lang": "go", - "source": "err = scalekitClient.Domain().DeleteDomain(ctx, \"dom_123\", \"org_123\")" + "source": "// Set a custom policy\ntimeout := int32(480)\nidleTimeout := int32(60)\nidleEnabled := true\n\nupdated, err := scalekitClient.Organization().UpdateOrganizationSessionPolicy(ctx, \"\", scalekit.OrganizationSessionPolicy{\n PolicySource: scalekit.SessionPolicySourceCustom,\n AbsoluteSessionTimeout: &timeout,\n AbsoluteSessionTimeoutUnit: scalekit.TimeUnitMinutes,\n IdleSessionTimeoutEnabled: &idleEnabled,\n IdleSessionTimeout: &idleTimeout,\n IdleSessionTimeoutUnit: scalekit.TimeUnitMinutes,\n})\nif err != nil {\n log.Fatal(err)\n}\n\n// Revert to application defaults\n_, err = scalekitClient.Organization().UpdateOrganizationSessionPolicy(ctx, \"\", scalekit.OrganizationSessionPolicy{\n PolicySource: scalekit.SessionPolicySourceApplication,\n})" }, { "label": "Java SDK", "lang": "java", - "source": "scalekitClient.domains().deleteDomain(organization.getId(), domain.getId());" + "source": "import com.google.protobuf.Int32Value;\nimport com.google.protobuf.BoolValue;\nimport com.scalekit.grpc.scalekit.v1.commons.TimeUnit;\nimport com.scalekit.grpc.scalekit.v1.organizations.OrganizationSessionPolicySettings;\nimport com.scalekit.grpc.scalekit.v1.organizations.SessionPolicyType;\n\n// Set a custom policy\nOrganizationSessionPolicySettings policy = OrganizationSessionPolicySettings.newBuilder()\n .setPolicySource(SessionPolicyType.CUSTOM)\n .setAbsoluteSessionTimeout(Int32Value.of(480))\n .setAbsoluteSessionTimeoutUnit(TimeUnit.MINUTES)\n .setIdleSessionTimeoutEnabled(BoolValue.of(true))\n .setIdleSessionTimeout(Int32Value.of(60))\n .setIdleSessionTimeoutUnit(TimeUnit.MINUTES)\n .build();\n\nOrganizationSessionPolicySettings updated =\n scalekitClient.organizations().updateOrganizationSessionPolicy(\"\", policy);\n\n// Revert to application defaults\nOrganizationSessionPolicySettings revert = OrganizationSessionPolicySettings.newBuilder()\n .setPolicySource(SessionPolicyType.APPLICATION)\n .build();\n\nscalekitClient.organizations().updateOrganizationSessionPolicy(\"\", revert);" } - ] + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OrganizationServiceUpdateOrganizationSessionPolicyBody" + } + } + }, + "required": true + } } }, "/api/v1/organizations/{organization_id}/settings/usermanagement": { @@ -4643,29 +5148,7 @@ } } } - }, - "x-codeSamples": [ - { - "label": "Node.js SDK", - "lang": "javascript", - "source": "const { permissions } = await scalekit.permission.listEffectiveRolePermissions(\"senior_editor\");" - }, - { - "label": "Python SDK", - "lang": "python", - "source": "response = scalekit_client.permissions.list_effective_role_permissions(role_name=\"senior_editor\")\npermissions = response.permissions" - }, - { - "label": "Go SDK", - "lang": "go", - "source": "resp, err := scalekitClient.Permission().ListEffectiveRolePermissions(ctx, \"senior_editor\")\nif err != nil {\n // handle error\n}\npermissions := resp.Permissions" - }, - { - "label": "Java SDK", - "lang": "java", - "source": "ListEffectiveRolePermissionsResponse response = scalekitClient.permissions().listEffectiveRolePermissions(\"senior_editor\");\nList permissions = response.getPermissionsList();" - } - ] + } } }, "/api/v1/roles/{role_name}/users:count": { @@ -5580,6 +6063,9 @@ ], "components": { "schemas": { + "ConnectedAccountServiceDisconnectConnectedAccountBody": { + "type": "object" + }, "HelpInfoLink": { "description": "A documentation or reference link.", "type": "object", @@ -5594,6 +6080,43 @@ } } }, + "OrganizationServiceUpdateOrganizationSessionPolicyBody": { + "type": "object", + "properties": { + "absolute_session_timeout": { + "description": "The absolute session timeout value. The unit is specified by absolute_session_timeout_unit. Omit when policy_source is APPLICATION.", + "type": "integer", + "format": "int32", + "examples": [360] + }, + "absolute_session_timeout_unit": { + "description": "Unit for absolute_session_timeout. Accepted values: 'MINUTES', 'HOURS', 'DAYS'. Defaults to MINUTES.", + "$ref": "#/components/schemas/commonsTimeUnit", + "examples": ["MINUTES"] + }, + "idle_session_timeout": { + "description": "The idle session timeout value. The unit is specified by idle_session_timeout_unit. Omit when idle_session_timeout_enabled is false.", + "type": "integer", + "format": "int32", + "examples": [84] + }, + "idle_session_timeout_enabled": { + "description": "Whether idle session timeout is enabled. Omit when policy_source is APPLICATION.", + "type": "boolean", + "examples": [true] + }, + "idle_session_timeout_unit": { + "description": "Unit for idle_session_timeout. Accepted values: 'MINUTES', 'HOURS', 'DAYS'. Defaults to MINUTES.", + "$ref": "#/components/schemas/commonsTimeUnit", + "examples": ["MINUTES"] + }, + "policy_source": { + "description": "Policy source. Send 'APPLICATION' to revert to application defaults. Send 'CUSTOM' with timeout values to activate a custom policy.", + "$ref": "#/components/schemas/organizationsSessionPolicyType", + "examples": ["CUSTOM"] + } + } + }, "OrganizationServiceUpsertUserManagementSettingsBody": { "type": "object", "properties": { @@ -6390,6 +6913,10 @@ } } }, + "commonsTimeUnit": { + "type": "string", + "enum": ["MINUTES", "HOURS", "DAYS"] + }, "commonsUserProfile": { "type": "object", "properties": { @@ -6501,6 +7028,10 @@ "type": "object", "title": "Authentication credentials container supporting multiple auth types", "properties": { + "google_dwd": { + "title": "Google Domain-Wide Delegation credentials", + "$ref": "#/components/schemas/connected_accountsGoogleDWDAuth" + }, "oauth_token": { "title": "OAuth 2.0 credentials", "$ref": "#/components/schemas/connected_accountsOauthToken" @@ -6640,16 +7171,26 @@ } }, "connected_accountsConnectorStatus": { - "description": "- ACTIVE: Account is connected and credentials are valid\n - EXPIRED: Access token has expired and needs refresh\n - PENDING_AUTH: Account awaiting user authorization (re-auth initiated)\n - PENDING_VERIFICATION: OAuth complete; awaiting user identity verification\nbefore activation", + "description": "- ACTIVE: Account is connected and credentials are valid\n - EXPIRED: Access token has expired and needs refresh\n - PENDING_AUTH: Account awaiting user authorization (re-auth initiated)\n - PENDING_VERIFICATION: OAuth complete; awaiting user identity verification\nbefore activation\n - DISCONNECTED: Account has been manually disconnected", "type": "string", "title": "Status of a connected account indicating its current state", - "enum": ["ACTIVE", "EXPIRED", "PENDING_AUTH", "PENDING_VERIFICATION"] + "enum": ["ACTIVE", "EXPIRED", "PENDING_AUTH", "PENDING_VERIFICATION", "DISCONNECTED"] }, "connected_accountsConnectorType": { - "description": "- OAUTH: OAuth 2.0 authorization with access and refresh tokens\n - API_KEY: Static API key authentication\n - BASIC_AUTH: HTTP Basic Authentication (username/password)\n - BEARER_TOKEN: Bearer token authentication\n - CUSTOM: Custom authentication mechanism\n - BASIC: Basic authentication (alias)", + "description": "- OAUTH: OAuth 2.0 authorization with access and refresh tokens\n - API_KEY: Static API key authentication\n - BASIC_AUTH: HTTP Basic Authentication (username/password)\n - BEARER_TOKEN: Bearer token authentication\n - CUSTOM: Custom authentication mechanism\n - BASIC: Basic authentication (alias)\n - OAUTH_M2M: OAuth 2.0 client credentials (machine-to-machine)\n - TRELLO_OAUTH1: Trello token-based OAuth1-style browser authorization\n - GOOGLE_DWD: Google Domain-Wide Delegation", "type": "string", "title": "Type of authentication mechanism used for the connected account", - "enum": ["OAUTH", "API_KEY", "BASIC_AUTH", "BEARER_TOKEN", "CUSTOM", "BASIC"] + "enum": [ + "OAUTH", + "API_KEY", + "BASIC_AUTH", + "BEARER_TOKEN", + "CUSTOM", + "BASIC", + "OAUTH_M2M", + "TRELLO_OAUTH1", + "GOOGLE_DWD" + ] }, "connected_accountsCreateConnectedAccountRequest": { "type": "object", @@ -6734,6 +7275,25 @@ "connected_accountsDeleteConnectedAccountResponse": { "type": "object" }, + "connected_accountsDisconnectConnectedAccountRequest": { + "type": "object", + "properties": { + "id": { + "description": "Unique identifier for the connected account to disconnect. Always prefixed with 'ca_'.", + "type": "string", + "examples": ["ca_24834495392086178"] + } + } + }, + "connected_accountsDisconnectConnectedAccountResponse": { + "type": "object", + "properties": { + "connected_account": { + "description": "The connected account with its updated DISCONNECTED status.", + "$ref": "#/components/schemas/connected_accountsConnectedAccount" + } + } + }, "connected_accountsGetConnectedAccountByIdentifierResponse": { "type": "object", "properties": { @@ -6743,6 +7303,15 @@ } } }, + "connected_accountsGetConnectedAccountResponse": { + "type": "object", + "properties": { + "connected_account": { + "description": "The connected account with its details and authentication status.", + "$ref": "#/components/schemas/connected_accountsConnectedAccount" + } + } + }, "connected_accountsGetMagicLinkForConnectedAccountRequest": { "type": "object", "properties": { @@ -6799,6 +7368,38 @@ } } }, + "connected_accountsGoogleDWDAuth": { + "description": "Google Domain-Wide Delegation authentication — used for GOOGLE_DWD connections.\nSend only subject in requests; access_token, scopes, and token_expires_at are response-only.", + "type": "object", + "properties": { + "access_token": { + "description": "OAuth access token acquired via the jwt-bearer grant. Present in responses only.", + "type": "string", + "readOnly": true, + "examples": ["ya29.a0AfH6SMBx..."] + }, + "scopes": { + "description": "OAuth scopes granted to this token. Present in responses only.", + "type": "array", + "items": { + "type": "string" + }, + "readOnly": true, + "examples": [["openid", "https://www.googleapis.com/auth/userinfo.email"]] + }, + "subject": { + "description": "Email address of the Google Workspace user to impersonate via Domain-Wide Delegation.", + "type": "string", + "examples": ["user@example.com"] + }, + "token_expires_at": { + "description": "When the access token expires. Present in responses only.", + "type": "string", + "format": "date-time", + "readOnly": true + } + } + }, "connected_accountsListConnectedAccountsResponse": { "type": "object", "properties": { @@ -7036,6 +7637,10 @@ "type": "boolean", "examples": [false] }, + "google_dwd_config": { + "description": "Configuration details for Google Domain-Wide Delegation. Present only when type is GOOGLE_DWD.", + "$ref": "#/components/schemas/connectionsGoogleDWDConfig" + }, "id": { "description": "Unique identifier for this connection. Used in API calls to reference this specific connection.", "type": "string", @@ -7138,7 +7743,10 @@ "BASIC", "BEARER", "API_KEY", - "WEBAUTHN" + "WEBAUTHN", + "OAUTH_M2M", + "TRELLO_OAUTH1", + "GOOGLE_DWD" ] }, "connectionsGetConnectionResponse": { @@ -7150,6 +7758,26 @@ } } }, + "connectionsGoogleDWDConfig": { + "type": "object", + "properties": { + "scopes": { + "description": "OAuth 2.0 scopes to request.", + "type": "array", + "items": { + "type": "string" + } + }, + "service_account_json": { + "description": "Google Cloud service account JSON key. Write-only: reads return a masked value.", + "type": "string" + }, + "token_uri": { + "description": "Google token endpoint. Defaults to https://oauth2.googleapis.com/token.", + "type": "string" + } + } + }, "connectionsIDPCertificate": { "type": "object", "properties": { @@ -7265,6 +7893,11 @@ "type": "string", "examples": ["offline"] }, + "app_name": { + "description": "Application name used by providers that require it as an authorize query parameter (e.g., Trello's app_name).", + "type": "string", + "examples": ["My Trello App"] + }, "authorize_uri": { "description": "Authorize URI", "type": "string", @@ -7285,6 +7918,16 @@ "type": "string", "examples": ["user_scope"] }, + "is_cimd": { + "description": "Indicates whether this connection was registered using Client ID Metadata Document (CIMD) instead of Dynamic Client Registration.", + "type": "boolean", + "readOnly": true, + "examples": [true] + }, + "optional_scopes": { + "description": "Optional scopes configuration for identity providers that support or require additional scopes to be sent in a custom field during authentication requests.", + "$ref": "#/components/schemas/connectionsOptionalScopes" + }, "pkce_enabled": { "description": "PKCE Enabled", "type": "boolean", @@ -7439,6 +8082,24 @@ "type": "string", "enum": ["openid", "profile", "email", "address", "phone"] }, + "connectionsOptionalScopes": { + "type": "object", + "properties": { + "field_name": { + "description": "Name of the field in which scope should be sent in the authentication request. This is required by some identity providers that expect scopes to be sent in a custom field instead of the standard 'scope' parameter.", + "type": "string", + "examples": ["optional_scope or bot_scope"] + }, + "scopes": { + "description": "List of optional scopes that can be requested during authentication", + "type": "array", + "items": { + "type": "string" + }, + "examples": [["scope1", "scope2"]] + } + } + }, "connectionsPasswordLessConfig": { "type": "object", "properties": { @@ -8137,6 +8798,16 @@ "type": "string", "format": "date-time", "examples": ["2025-09-01T12:14:43.110455Z"] + }, + "verification_method": { + "description": "Method that determines how domain ownership is verified.\n- ADMIN: domain is marked verified without DNS validation, typically by an admin.\n- DNS: domain must be verified by adding a TXT record to your DNS configuration.\n- NOT_APPLICABLE: verification does not apply to this domain type.", + "$ref": "#/components/schemas/domainsVerificationMethod", + "examples": ["ADMIN"] + }, + "verification_status": { + "description": "Verification status of the domain.\n- PENDING: DNS TXT record has not been validated yet.\n- VERIFIED: domain confirmed via DNS TXT record validation or admin approval.\n- AUTO_VERIFIED: domain verified automatically without DNS changes.\n- FAILED: DNS TXT record was not validated within the verification window.", + "$ref": "#/components/schemas/domainsVerificationStatus", + "examples": ["AUTO_VERIFIED"] } } }, @@ -8179,6 +8850,14 @@ } } }, + "domainsVerificationMethod": { + "type": "string", + "enum": ["ADMIN", "DNS", "NOT_APPLICABLE"] + }, + "domainsVerificationStatus": { + "type": "string", + "enum": ["PENDING", "VERIFIED", "FAILED", "AUTO_VERIFIED"] + }, "errdetailsDebugInfo": { "description": "Describes additional debugging info.", "type": "object", @@ -8351,6 +9030,15 @@ } } }, + "organizationsGetOrganizationSessionPolicyResponse": { + "type": "object", + "properties": { + "policy": { + "description": "The session policy for the organization.", + "$ref": "#/components/schemas/organizationsOrganizationSessionPolicySettings" + } + } + }, "organizationsLink": { "type": "object", "properties": { @@ -8447,6 +9135,14 @@ "title": "Organization Settings", "$ref": "#/components/schemas/organizationsOrganizationSettings" }, + "slug": { + "description": "DNS-safe slug for dynamic redirect URI resolution. Must be 1-63 chars, lowercase alphanumeric and hyphens, must start and end with an alphanumeric character. Unique per environment.", + "type": "string", + "maxLength": 63, + "minLength": 1, + "pattern": "^[a-z0-9]([a-z0-9]|-[a-z0-9])*$", + "examples": ["acme"] + }, "update_time": { "description": "Timestamp when the organization was last updated", "type": "string", @@ -8456,6 +9152,43 @@ } } }, + "organizationsOrganizationSessionPolicySettings": { + "type": "object", + "properties": { + "absolute_session_timeout": { + "description": "The absolute session timeout value. The unit is specified by absolute_session_timeout_unit. Omitted when policy_source is 'environment'.", + "type": "integer", + "format": "int32", + "examples": [360] + }, + "absolute_session_timeout_unit": { + "description": "Unit for absolute_session_timeout. Accepted values: 'minutes', 'hours', 'days'. Responses always return 'minutes'.", + "$ref": "#/components/schemas/commonsTimeUnit", + "examples": ["minutes"] + }, + "idle_session_timeout": { + "description": "The idle session timeout value. The unit is specified by idle_session_timeout_unit. Omitted when idle_session_timeout_enabled is false or policy_source is 'environment'.", + "type": "integer", + "format": "int32", + "examples": [84] + }, + "idle_session_timeout_enabled": { + "description": "Whether idle session timeout is enabled for this organization. Omitted when policy_source is 'environment'.", + "type": "boolean", + "examples": [true] + }, + "idle_session_timeout_unit": { + "description": "Unit for idle_session_timeout. Accepted values: 'minutes', 'hours', 'days'. Responses always return 'minutes'.", + "$ref": "#/components/schemas/commonsTimeUnit", + "examples": ["minutes"] + }, + "policy_source": { + "description": "Policy source. 'APPLICATION' means the organization inherits the application-level session policy. 'CUSTOM' means organization-specific timeout values are active.", + "$ref": "#/components/schemas/organizationsSessionPolicyType", + "examples": ["CUSTOM"] + } + } + }, "organizationsOrganizationSettings": { "description": "Configuration options that control organization-level features and capabilities", "type": "object", @@ -8509,7 +9242,7 @@ "examples": [true] }, "name": { - "description": "Feature identifier. Supported values include: \"sso\" (Single Sign-On), \"directory_sync\" (Directory Synchronization)", + "description": "Feature identifier. Supported values include: \"sso\" (Single Sign-On), \"directory_sync\" (Directory Synchronization), \"domain_verification\" (Domain Verification), \"session_policy\" (Organization-level session policy override)", "type": "string", "examples": ["sso"] } @@ -8526,6 +9259,10 @@ } } }, + "organizationsSessionPolicyType": { + "type": "string", + "enum": ["APPLICATION", "CUSTOM"] + }, "organizationsUpdateOrganizationResponse": { "type": "object", "properties": { @@ -8535,6 +9272,15 @@ } } }, + "organizationsUpdateOrganizationSessionPolicyResponse": { + "type": "object", + "properties": { + "policy": { + "description": "The updated session policy for the organization.", + "$ref": "#/components/schemas/organizationsOrganizationSessionPolicySettings" + } + } + }, "organizationsUpsertUserManagementSettingsResponse": { "type": "object", "properties": { @@ -9371,6 +10117,11 @@ "toolsExecuteToolRequest": { "type": "object", "properties": { + "agent_run_id": { + "description": "Optional. Customer-supplied identifier grouping multiple tool calls into a single agent run. Useful for correlating logs across an agentic workflow.", + "type": "string", + "examples": ["run_abc123"] + }, "connected_account_id": { "description": "Optional. The unique ID of the connected account. Use this to directly identify the connected account instead of using identifier + connector combination.", "type": "string", @@ -10065,6 +10816,14 @@ "additionalProperties": { "type": "string" } + }, + "slug": { + "description": "DNS-safe slug for dynamic redirect URI resolution (e.g. acme for https://acme.example.com/callback). Lowercase alphanumeric and hyphens, 1-63 chars, must start and end with alphanumeric, unique per environment.", + "type": "string", + "maxLength": 63, + "minLength": 1, + "pattern": "^[a-z0-9]([a-z0-9]|-[a-z0-9])*$", + "examples": ["acme"] } } }, @@ -10093,6 +10852,14 @@ "industry": "technology" } ] + }, + "slug": { + "description": "DNS-safe slug for dynamic redirect URI resolution. Lowercase alphanumeric and hyphens, 1-63 chars, must start and end with alphanumeric, unique per environment.", + "type": "string", + "maxLength": 63, + "minLength": 1, + "pattern": "^[a-z0-9]([a-z0-9]|-[a-z0-9])*$", + "examples": ["acme"] } } }, diff --git a/public/api/scalekit.scalar.yaml b/public/api/scalekit.scalar.yaml index aea329809..dbc78602a 100644 --- a/public/api/scalekit.scalar.yaml +++ b/public/api/scalekit.scalar.yaml @@ -375,6 +375,44 @@ paths: schema: $ref: '#/components/schemas/connected_accountsCreateConnectedAccountRequest' required: true + /api/v1/connected_accounts/-:disconnect: + post: + description: Disconnects a connected account by setting its status to + DISCONNECTED. The account record is retained but is marked as no longer + active. + tags: + - Connected Accounts + summary: Disconnect a connected account + operationId: ConnectedAccountService_DisconnectConnectedAccount2 + responses: + '200': + description: Successfully disconnected the connected account + content: + application/json: + schema: + $ref: '#/components/schemas/connected_accountsDisconnectConnectedAccountResponse' + '400': + description: Invalid request - missing or malformed connected account + ID + content: + application/json: + schema: {} + '401': + description: Authentication required - missing or invalid access token + content: + application/json: + schema: {} + '404': + description: Connected account not found + content: + application/json: + schema: {} + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/connected_accountsDisconnectConnectedAccountRequest' + required: true /api/v1/connected_accounts/auth: get: description: Retrieves complete authentication details for a connected @@ -438,6 +476,67 @@ paths: content: application/json: schema: {} + /api/v1/connected_accounts/details: + get: + description: Returns metadata for a connected account including status, + connector type, provider, and configuration without exposing stored + authorization credentials. Look up by account ID, or by a combination of + organization (or user), connector, and external identifier. + tags: + - Connected Accounts + summary: Get connected account details + operationId: ConnectedAccountService_GetConnectedAccountDetails + parameters: + - schema: + type: string + description: Organization ID for the connector + name: organization_id + in: query + - schema: + type: string + description: User ID for the connector + name: user_id + in: query + - schema: + type: string + description: Connector identifier + name: connector + in: query + - schema: + type: string + description: The unique identifier for the connected account within + the third-party service (e.g., email address, user ID, workspace + identifier). + name: identifier + in: query + - schema: + type: string + description: Unique identifier for the connected account + name: id + in: query + responses: + '200': + description: Successfully retrieved connected account details + content: + application/json: + schema: + $ref: '#/components/schemas/connected_accountsGetConnectedAccountByIdentifierResponse' + '400': + description: Invalid request - missing required query parameters + content: + application/json: + schema: {} + '401': + description: Authentication required - missing or invalid access token + content: + application/json: + schema: {} + '404': + description: Connected account not found - no account matches the + specified criteria + content: + application/json: + schema: {} /api/v1/connected_accounts/magic_link: post: description: Creates a time-limited magic link for connecting or @@ -474,6 +573,46 @@ paths: schema: $ref: '#/components/schemas/connected_accountsGetMagicLinkForConnectedAccountRequest' required: true + /api/v1/connected_accounts/this: + get: + description: Retrieves a connected account by its unique ID. Use the path + '/this' (e.g. /api/v1/connected_accounts/this) to retrieve the connected + account associated with the current token context. + tags: + - Connected Accounts + summary: Get a connected account + operationId: ConnectedAccountService_GetConnectedAccount + parameters: + - schema: + type: string + description: Unique identifier for the connected account. Always + prefixed with 'ca_'. If omitted (via the /this path), the connected + account is resolved from the current token context. + name: id + in: query + responses: + '200': + description: Successfully retrieved the connected account + content: + application/json: + schema: + $ref: '#/components/schemas/connected_accountsGetConnectedAccountResponse' + '400': + description: Invalid request - missing or malformed connected account + ID + content: + application/json: + schema: {} + '401': + description: Authentication required - missing or invalid access token + content: + application/json: + schema: {} + '404': + description: Connected account not found + content: + application/json: + schema: {} /api/v1/connected_accounts/user/verify: post: description: Confirms the user assertion and activates the connected @@ -519,6 +658,93 @@ paths: schema: $ref: '#/components/schemas/connected_accountsVerifyConnectedAccountUserRequest' required: true + /api/v1/connected_accounts/{id}: + get: + description: Retrieves a connected account by its unique ID. Use the path + '/this' (e.g. /api/v1/connected_accounts/this) to retrieve the connected + account associated with the current token context. + tags: + - Connected Accounts + summary: Get a connected account + operationId: ConnectedAccountService_GetConnectedAccount2 + parameters: + - schema: + type: string + description: Unique identifier for the connected account. Always + prefixed with 'ca_'. If omitted (via the /this path), the connected + account is resolved from the current token context. + name: id + in: path + required: true + responses: + '200': + description: Successfully retrieved the connected account + content: + application/json: + schema: + $ref: '#/components/schemas/connected_accountsGetConnectedAccountResponse' + '400': + description: Invalid request - missing or malformed connected account + ID + content: + application/json: + schema: {} + '401': + description: Authentication required - missing or invalid access token + content: + application/json: + schema: {} + '404': + description: Connected account not found + content: + application/json: + schema: {} + /api/v1/connected_accounts/{id}:disconnect: + post: + description: Disconnects a connected account by setting its status to + DISCONNECTED. The account record is retained but is marked as no longer + active. + tags: + - Connected Accounts + summary: Disconnect a connected account + operationId: ConnectedAccountService_DisconnectConnectedAccount + parameters: + - schema: + type: string + description: Unique identifier for the connected account to + disconnect. Always prefixed with 'ca_'. + name: id + in: path + required: true + responses: + '200': + description: Successfully disconnected the connected account + content: + application/json: + schema: + $ref: '#/components/schemas/connected_accountsDisconnectConnectedAccountResponse' + '400': + description: Invalid request - missing or malformed connected account + ID + content: + application/json: + schema: {} + '401': + description: Authentication required - missing or invalid access token + content: + application/json: + schema: {} + '404': + description: Connected account not found + content: + application/json: + schema: {} + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ConnectedAccountServiceDisconnectConnectedAccountBody' + required: true /api/v1/connected_accounts:delete: post: description: Permanently removes a connected account and revokes all @@ -960,6 +1186,8 @@ paths: schema: description: Membership details to create. Required fields must be provided. + required: + - membership $ref: '#/components/schemas/v1usersCreateMembership' required: true delete: @@ -1995,6 +2223,66 @@ paths: scalekitClient.roles().deleteOrganizationRole("org_123", "org_role_admin", "org_role_member"); + /api/v1/organizations/{org_id}/roles/{role_name}/base: + delete: + description: Removes the base role inheritance relationship for a + specified organization role, effectively eliminating all inherited + permissions from the base role. Use this endpoint when you want to break + the hierarchical relationship between roles and remove inherited + permissions within the organization. The role will retain only its + directly assigned permissions after this operation. This action cannot + be undone, so ensure the role has sufficient direct permissions before + removing inheritance. + tags: + - Roles + summary: Remove organization role inheritance + operationId: RolesService_DeleteOrganizationRoleBase + parameters: + - schema: + type: string + description: Unique identifier to an Organization + name: org_id + in: path + required: true + - schema: + type: string + description: Name of the organization role to remove base from + name: role_name + in: path + required: true + responses: + '200': + description: Organization role base inheritance relationship + successfully removed. The role now has only its directly assigned + permissions. + content: + application/json: + schema: {} + x-codeSamples: + - label: Node.js SDK + lang: javascript + source: await scalekit.role.deleteOrganizationRoleBase("org_123", + "senior_editor"); + - label: Python SDK + lang: python + source: |- + scalekit_client.roles.delete_organization_role_base( + org_id="org_123", + role_name="senior_editor" + ) + - label: Go SDK + lang: go + source: >- + err := scalekitClient.Role().DeleteOrganizationRoleBase(ctx, + "org_123", "senior_editor") + + if err != nil { + // handle error + } + - label: Java SDK + lang: java + source: scalekitClient.roles().deleteOrganizationRoleBase("org_123", + "senior_editor"); /api/v1/organizations/{org_id}/roles:set_defaults: patch: description: Updates the default member role for the specified @@ -3425,6 +3713,230 @@ paths: lang: java source: scalekitClient.domains().deleteDomain(organization.getId(), domain.getId()); + /api/v1/organizations/{organization_id}/session-policy: + get: + description: Retrieves the session policy for an organization. Returns + session_policy='APPLICATION' if the organization inherits the + application-level defaults, or session_policy='CUSTOM' with the + configured values if a custom policy is active. + tags: + - Organizations + summary: Get organization session policy + operationId: OrganizationService_GetOrganizationSessionPolicy + parameters: + - schema: + type: string + description: The unique identifier of the organization whose session + policy is being requested. + name: organization_id + in: path + required: true + responses: + '200': + description: Session policy retrieved successfully. + content: + application/json: + schema: + $ref: '#/components/schemas/organizationsGetOrganizationSessionPolicyResponse' + '404': + description: Organization not found. + content: + application/json: + schema: {} + x-codeSamples: + - label: Node.js SDK + lang: javascript + source: |- + const policy = await scalekit.organization.getOrganizationSessionPolicy(''); + + console.log('Policy source:', policy.policySource); + console.log('Absolute timeout (minutes):', policy.absoluteSessionTimeout); + console.log('Idle timeout enabled:', policy.idleSessionTimeoutEnabled); + - label: Python SDK + lang: python + source: |- + from scalekit.v1.organizations.organizations_pb2 import SessionPolicyType + + response, _ = scalekit_client.organization.get_organization_session_policy('') + policy = response.policy + + if policy.policy_source == SessionPolicyType.CUSTOM: + print('Absolute timeout (minutes):', policy.absolute_session_timeout.value) + print('Idle timeout enabled:', policy.idle_session_timeout_enabled.value) + - label: Go SDK + lang: go + source: >- + policy, err := + scalekitClient.Organization().GetOrganizationSessionPolicy(ctx, + "") + + if err != nil { + log.Fatal(err) + } + + + if policy.PolicySource == scalekit.SessionPolicySourceCustom { + fmt.Println("Absolute timeout (minutes):", policy.AbsoluteSessionTimeout.GetValue()) + fmt.Println("Idle timeout enabled:", policy.IdleSessionTimeoutEnabled.GetValue()) + } + - label: Java SDK + lang: java + source: |- + import com.scalekit.grpc.scalekit.v1.organizations.OrganizationSessionPolicySettings; + import com.scalekit.grpc.scalekit.v1.organizations.SessionPolicyType; + + OrganizationSessionPolicySettings policy = + scalekitClient.organizations().getOrganizationSessionPolicy(""); + + if (policy.getPolicySource() == SessionPolicyType.CUSTOM) { + System.out.println("Absolute timeout (minutes): " + policy.getAbsoluteSessionTimeout().getValue()); + System.out.println("Idle timeout enabled: " + policy.getIdleSessionTimeoutEnabled().getValue()); + } + patch: + description: Sets a custom session policy for an organization or reverts + to application-level settings. Send session_policy='APPLICATION' to + revert to application defaults. Send session_policy='CUSTOM' with + timeout values to activate a custom policy. + tags: + - Organizations + summary: Update organization session policy + operationId: OrganizationService_UpdateOrganizationSessionPolicy + parameters: + - schema: + type: string + description: The unique identifier of the organization whose session + policy is being updated. + name: organization_id + in: path + required: true + responses: + '200': + description: Session policy updated successfully. + content: + application/json: + schema: + $ref: '#/components/schemas/organizationsUpdateOrganizationSessionPolicyResponse' + '404': + description: Organization not found. + content: + application/json: + schema: {} + x-codeSamples: + - label: Node.js SDK + lang: javascript + source: |- + // Set a custom policy + const updated = await scalekit.organization.updateOrganizationSessionPolicy('', { + policySource: 'CUSTOM', + absoluteSessionTimeout: 480, + absoluteSessionTimeoutUnit: 'MINUTES', + idleSessionTimeoutEnabled: true, + idleSessionTimeout: 60, + idleSessionTimeoutUnit: 'MINUTES', + }); + + // Revert to application defaults + await scalekit.organization.updateOrganizationSessionPolicy('', { + policySource: 'APPLICATION', + }); + - label: Python SDK + lang: python + source: >- + from scalekit.v1.organizations.organizations_pb2 import + SessionPolicyType + + from scalekit.v1.commons.commons_pb2 import TimeUnit + + + # Set a custom policy + + response, _ = + scalekit_client.organization.update_organization_session_policy( + organization_id='', + policy_source=SessionPolicyType.CUSTOM, + absolute_session_timeout=480, + absolute_session_timeout_unit=TimeUnit.MINUTES, + idle_session_timeout_enabled=True, + idle_session_timeout=60, + idle_session_timeout_unit=TimeUnit.MINUTES, + ) + + + # Revert to application defaults + + scalekit_client.organization.update_organization_session_policy( + organization_id='', + policy_source=SessionPolicyType.APPLICATION, + ) + - label: Go SDK + lang: go + source: >- + // Set a custom policy + + timeout := int32(480) + + idleTimeout := int32(60) + + idleEnabled := true + + + updated, err := + scalekitClient.Organization().UpdateOrganizationSessionPolicy(ctx, + "", scalekit.OrganizationSessionPolicy{ + PolicySource: scalekit.SessionPolicySourceCustom, + AbsoluteSessionTimeout: &timeout, + AbsoluteSessionTimeoutUnit: scalekit.TimeUnitMinutes, + IdleSessionTimeoutEnabled: &idleEnabled, + IdleSessionTimeout: &idleTimeout, + IdleSessionTimeoutUnit: scalekit.TimeUnitMinutes, + }) + + if err != nil { + log.Fatal(err) + } + + + // Revert to application defaults + + _, err = + scalekitClient.Organization().UpdateOrganizationSessionPolicy(ctx, + "", scalekit.OrganizationSessionPolicy{ + PolicySource: scalekit.SessionPolicySourceApplication, + }) + - label: Java SDK + lang: java + source: |- + import com.google.protobuf.Int32Value; + import com.google.protobuf.BoolValue; + import com.scalekit.grpc.scalekit.v1.commons.TimeUnit; + import com.scalekit.grpc.scalekit.v1.organizations.OrganizationSessionPolicySettings; + import com.scalekit.grpc.scalekit.v1.organizations.SessionPolicyType; + + // Set a custom policy + OrganizationSessionPolicySettings policy = OrganizationSessionPolicySettings.newBuilder() + .setPolicySource(SessionPolicyType.CUSTOM) + .setAbsoluteSessionTimeout(Int32Value.of(480)) + .setAbsoluteSessionTimeoutUnit(TimeUnit.MINUTES) + .setIdleSessionTimeoutEnabled(BoolValue.of(true)) + .setIdleSessionTimeout(Int32Value.of(60)) + .setIdleSessionTimeoutUnit(TimeUnit.MINUTES) + .build(); + + OrganizationSessionPolicySettings updated = + scalekitClient.organizations().updateOrganizationSessionPolicy("", policy); + + // Revert to application defaults + OrganizationSessionPolicySettings revert = OrganizationSessionPolicySettings.newBuilder() + .setPolicySource(SessionPolicyType.APPLICATION) + .build(); + + scalekitClient.organizations().updateOrganizationSessionPolicy("", revert); + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/OrganizationServiceUpdateOrganizationSessionPolicyBody' + required: true /api/v1/organizations/{organization_id}/settings/usermanagement: patch: description: Upsert user management settings for an organization @@ -5214,33 +5726,6 @@ paths: application/json: schema: $ref: '#/components/schemas/rolesListEffectiveRolePermissionsResponse' - x-codeSamples: - - label: Node.js SDK - lang: javascript - source: const { permissions } = await - scalekit.permission.listEffectiveRolePermissions("senior_editor"); - - label: Python SDK - lang: python - source: |- - response = scalekit_client.permissions.list_effective_role_permissions(role_name="senior_editor") - permissions = response.permissions - - label: Go SDK - lang: go - source: >- - resp, err := - scalekitClient.Permission().ListEffectiveRolePermissions(ctx, - "senior_editor") - - if err != nil { - // handle error - } - - permissions := resp.Permissions - - label: Java SDK - lang: java - source: |- - ListEffectiveRolePermissionsResponse response = scalekitClient.permissions().listEffectiveRolePermissions("senior_editor"); - List permissions = response.getPermissionsList(); /api/v1/roles/{role_name}/users:count: get: description: Retrieves the total number of users currently assigned to the @@ -6238,6 +6723,8 @@ servers: - url: https://$SCALEKIT_ENVIRONMENT_URL components: schemas: + ConnectedAccountServiceDisconnectConnectedAccountBody: + type: object HelpInfoLink: description: A documentation or reference link. type: object @@ -6250,6 +6737,50 @@ components: description: Absolute URL to the documentation page (e.g. "https://docs.scalekit.com/..."). type: string + OrganizationServiceUpdateOrganizationSessionPolicyBody: + type: object + properties: + absolute_session_timeout: + description: The absolute session timeout value. The unit is specified + by absolute_session_timeout_unit. Omit when policy_source is + APPLICATION. + type: integer + format: int32 + examples: + - 360 + absolute_session_timeout_unit: + description: "Unit for absolute_session_timeout. Accepted values: 'MINUTES', + 'HOURS', 'DAYS'. Defaults to MINUTES." + $ref: '#/components/schemas/commonsTimeUnit' + examples: + - MINUTES + idle_session_timeout: + description: The idle session timeout value. The unit is specified by + idle_session_timeout_unit. Omit when idle_session_timeout_enabled is + false. + type: integer + format: int32 + examples: + - 84 + idle_session_timeout_enabled: + description: Whether idle session timeout is enabled. Omit when + policy_source is APPLICATION. + type: boolean + examples: + - true + idle_session_timeout_unit: + description: "Unit for idle_session_timeout. Accepted values: 'MINUTES', + 'HOURS', 'DAYS'. Defaults to MINUTES." + $ref: '#/components/schemas/commonsTimeUnit' + examples: + - MINUTES + policy_source: + description: Policy source. Send 'APPLICATION' to revert to + application defaults. Send 'CUSTOM' with timeout values to activate + a custom policy. + $ref: '#/components/schemas/organizationsSessionPolicyType' + examples: + - CUSTOM OrganizationServiceUpsertUserManagementSettingsBody: type: object properties: @@ -7061,6 +7592,12 @@ components: type: string examples: - team_dev + commonsTimeUnit: + type: string + enum: + - MINUTES + - HOURS + - DAYS commonsUserProfile: type: object properties: @@ -7222,6 +7759,9 @@ components: type: object title: Authentication credentials container supporting multiple auth types properties: + google_dwd: + title: Google Domain-Wide Delegation credentials + $ref: '#/components/schemas/connected_accountsGoogleDWDAuth' oauth_token: title: OAuth 2.0 credentials $ref: '#/components/schemas/connected_accountsOauthToken' @@ -7370,6 +7910,7 @@ components: - PENDING_AUTH: Account awaiting user authorization (re-auth initiated) - PENDING_VERIFICATION: OAuth complete; awaiting user identity verification before activation + - DISCONNECTED: Account has been manually disconnected type: string title: Status of a connected account indicating its current state enum: @@ -7377,6 +7918,7 @@ components: - EXPIRED - PENDING_AUTH - PENDING_VERIFICATION + - DISCONNECTED connected_accountsConnectorType: description: |- - OAUTH: OAuth 2.0 authorization with access and refresh tokens @@ -7385,6 +7927,9 @@ components: - BEARER_TOKEN: Bearer token authentication - CUSTOM: Custom authentication mechanism - BASIC: Basic authentication (alias) + - OAUTH_M2M: OAuth 2.0 client credentials (machine-to-machine) + - TRELLO_OAUTH1: Trello token-based OAuth1-style browser authorization + - GOOGLE_DWD: Google Domain-Wide Delegation type: string title: Type of authentication mechanism used for the connected account enum: @@ -7394,6 +7939,9 @@ components: - BEARER_TOKEN - CUSTOM - BASIC + - OAUTH_M2M + - TRELLO_OAUTH1 + - GOOGLE_DWD connected_accountsCreateConnectedAccountRequest: type: object properties: @@ -7471,6 +8019,22 @@ components: - user_121312434123312 connected_accountsDeleteConnectedAccountResponse: type: object + connected_accountsDisconnectConnectedAccountRequest: + type: object + properties: + id: + description: Unique identifier for the connected account to + disconnect. Always prefixed with 'ca_'. + type: string + examples: + - ca_24834495392086178 + connected_accountsDisconnectConnectedAccountResponse: + type: object + properties: + connected_account: + description: The connected account with its updated DISCONNECTED + status. + $ref: '#/components/schemas/connected_accountsConnectedAccount' connected_accountsGetConnectedAccountByIdentifierResponse: type: object properties: @@ -7479,6 +8043,13 @@ components: sensitive authorization credentials (access tokens, refresh tokens, scopes). Handle with appropriate access controls. $ref: '#/components/schemas/connected_accountsConnectedAccount' + connected_accountsGetConnectedAccountResponse: + type: object + properties: + connected_account: + description: The connected account with its details and authentication + status. + $ref: '#/components/schemas/connected_accountsConnectedAccount' connected_accountsGetMagicLinkForConnectedAccountRequest: type: object properties: @@ -7534,6 +8105,43 @@ components: type: string examples: - https://notion.com/oauth/authorize?client_id=... + connected_accountsGoogleDWDAuth: + description: >- + Google Domain-Wide Delegation authentication — used for GOOGLE_DWD + connections. + + Send only subject in requests; access_token, scopes, and + token_expires_at are response-only. + type: object + properties: + access_token: + description: OAuth access token acquired via the jwt-bearer grant. + Present in responses only. + type: string + readOnly: true + examples: + - ya29.a0AfH6SMBx... + scopes: + description: OAuth scopes granted to this token. Present in responses + only. + type: array + items: + type: string + readOnly: true + examples: + - - openid + - https://www.googleapis.com/auth/userinfo.email + subject: + description: Email address of the Google Workspace user to impersonate + via Domain-Wide Delegation. + type: string + examples: + - user@example.com + token_expires_at: + description: When the access token expires. Present in responses only. + type: string + format: date-time + readOnly: true connected_accountsListConnectedAccountsResponse: type: object properties: @@ -7758,6 +8366,10 @@ components: type: boolean examples: - false + google_dwd_config: + description: Configuration details for Google Domain-Wide Delegation. + Present only when type is GOOGLE_DWD. + $ref: '#/components/schemas/connectionsGoogleDWDConfig' id: description: Unique identifier for this connection. Used in API calls to reference this specific connection. @@ -7866,6 +8478,9 @@ components: - BEARER - API_KEY - WEBAUTHN + - OAUTH_M2M + - TRELLO_OAUTH1 + - GOOGLE_DWD connectionsGetConnectionResponse: type: object properties: @@ -7874,6 +8489,22 @@ components: configuration, protocol settings, status, and all metadata. Contains everything needed to understand the connection's current state. $ref: '#/components/schemas/connectionsConnection' + connectionsGoogleDWDConfig: + type: object + properties: + scopes: + description: OAuth 2.0 scopes to request. + type: array + items: + type: string + service_account_json: + description: 'Google Cloud service account JSON key. Write-only: reads return + a masked value.' + type: string + token_uri: + description: Google token endpoint. Defaults to + https://oauth2.googleapis.com/token. + type: string connectionsIDPCertificate: type: object properties: @@ -7987,6 +8618,12 @@ components: type: string examples: - offline + app_name: + description: Application name used by providers that require it as an + authorize query parameter (e.g., Trello's app_name). + type: string + examples: + - My Trello App authorize_uri: description: Authorize URI type: string @@ -8007,6 +8644,19 @@ components: type: string examples: - user_scope + is_cimd: + description: Indicates whether this connection was registered using + Client ID Metadata Document (CIMD) instead of Dynamic Client + Registration. + type: boolean + readOnly: true + examples: + - true + optional_scopes: + description: Optional scopes configuration for identity providers that + support or require additional scopes to be sent in a custom field + during authentication requests. + $ref: '#/components/schemas/connectionsOptionalScopes' pkce_enabled: description: PKCE Enabled type: boolean @@ -8167,6 +8817,26 @@ components: - email - address - phone + connectionsOptionalScopes: + type: object + properties: + field_name: + description: Name of the field in which scope should be sent in the + authentication request. This is required by some identity providers + that expect scopes to be sent in a custom field instead of the + standard 'scope' parameter. + type: string + examples: + - optional_scope or bot_scope + scopes: + description: List of optional scopes that can be requested during + authentication + type: array + items: + type: string + examples: + - - scope1 + - scope2 connectionsPasswordLessConfig: type: object properties: @@ -8817,6 +9487,36 @@ components: format: date-time examples: - 2025-09-01T12:14:43.110455Z + verification_method: + description: >- + Method that determines how domain ownership is verified. + + - ADMIN: domain is marked verified without DNS validation, typically + by an admin. + + - DNS: domain must be verified by adding a TXT record to your DNS + configuration. + + - NOT_APPLICABLE: verification does not apply to this domain type. + $ref: '#/components/schemas/domainsVerificationMethod' + examples: + - ADMIN + verification_status: + description: >- + Verification status of the domain. + + - PENDING: DNS TXT record has not been validated yet. + + - VERIFIED: domain confirmed via DNS TXT record validation or admin + approval. + + - AUTO_VERIFIED: domain verified automatically without DNS changes. + + - FAILED: DNS TXT record was not validated within the verification + window. + $ref: '#/components/schemas/domainsVerificationStatus' + examples: + - AUTO_VERIFIED domainsDomainType: type: string enum: @@ -8854,6 +9554,19 @@ components: format: int32 examples: - 1 + domainsVerificationMethod: + type: string + enum: + - ADMIN + - DNS + - NOT_APPLICABLE + domainsVerificationStatus: + type: string + enum: + - PENDING + - VERIFIED + - FAILED + - AUTO_VERIFIED errdetailsDebugInfo: description: Describes additional debugging info. type: object @@ -9012,6 +9725,12 @@ components: organization: description: The newly created organization $ref: '#/components/schemas/organizationsOrganization' + organizationsGetOrganizationSessionPolicyResponse: + type: object + properties: + policy: + description: The session policy for the organization. + $ref: '#/components/schemas/organizationsOrganizationSessionPolicySettings' organizationsLink: type: object properties: @@ -9109,6 +9828,16 @@ components: settings: title: Organization Settings $ref: '#/components/schemas/organizationsOrganizationSettings' + slug: + description: DNS-safe slug for dynamic redirect URI resolution. Must + be 1-63 chars, lowercase alphanumeric and hyphens, must start and + end with an alphanumeric character. Unique per environment. + type: string + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([a-z0-9]|-[a-z0-9])*$ + examples: + - acme update_time: description: Timestamp when the organization was last updated type: string @@ -9116,6 +9845,50 @@ components: title: Updated time examples: - 2025-02-15T06:23:44.560000Z + organizationsOrganizationSessionPolicySettings: + type: object + properties: + absolute_session_timeout: + description: The absolute session timeout value. The unit is specified + by absolute_session_timeout_unit. Omitted when policy_source is + 'environment'. + type: integer + format: int32 + examples: + - 360 + absolute_session_timeout_unit: + description: "Unit for absolute_session_timeout. Accepted values: 'minutes', + 'hours', 'days'. Responses always return 'minutes'." + $ref: '#/components/schemas/commonsTimeUnit' + examples: + - minutes + idle_session_timeout: + description: The idle session timeout value. The unit is specified by + idle_session_timeout_unit. Omitted when idle_session_timeout_enabled + is false or policy_source is 'environment'. + type: integer + format: int32 + examples: + - 84 + idle_session_timeout_enabled: + description: Whether idle session timeout is enabled for this + organization. Omitted when policy_source is 'environment'. + type: boolean + examples: + - true + idle_session_timeout_unit: + description: "Unit for idle_session_timeout. Accepted values: 'minutes', + 'hours', 'days'. Responses always return 'minutes'." + $ref: '#/components/schemas/commonsTimeUnit' + examples: + - minutes + policy_source: + description: Policy source. 'APPLICATION' means the organization + inherits the application-level session policy. 'CUSTOM' means + organization-specific timeout values are active. + $ref: '#/components/schemas/organizationsSessionPolicyType' + examples: + - CUSTOM organizationsOrganizationSettings: description: Configuration options that control organization-level features and capabilities @@ -9158,7 +9931,9 @@ components: - true name: description: 'Feature identifier. Supported values include: "sso" (Single - Sign-On), "directory_sync" (Directory Synchronization)' + Sign-On), "directory_sync" (Directory Synchronization), "domain_verification" + (Domain Verification), "session_policy" (Organization-level session policy + override)' type: string examples: - sso @@ -9174,12 +9949,23 @@ components: format: int32 examples: - 100 + organizationsSessionPolicyType: + type: string + enum: + - APPLICATION + - CUSTOM organizationsUpdateOrganizationResponse: type: object properties: organization: description: Updated organization details $ref: '#/components/schemas/organizationsOrganization' + organizationsUpdateOrganizationSessionPolicyResponse: + type: object + properties: + policy: + description: The updated session policy for the organization. + $ref: '#/components/schemas/organizationsOrganizationSessionPolicySettings' organizationsUpsertUserManagementSettingsResponse: type: object properties: @@ -10008,6 +10794,13 @@ components: toolsExecuteToolRequest: type: object properties: + agent_run_id: + description: Optional. Customer-supplied identifier grouping multiple + tool calls into a single agent run. Useful for correlating logs + across an agentic workflow. + type: string + examples: + - run_abc123 connected_account_id: description: Optional. The unique ID of the connected account. Use this to directly identify the connected account instead of using @@ -10704,6 +11497,17 @@ components: type: object additionalProperties: type: string + slug: + description: DNS-safe slug for dynamic redirect URI resolution (e.g. + acme for https://acme.example.com/callback). Lowercase alphanumeric + and hyphens, 1-63 chars, must start and end with alphanumeric, + unique per environment. + type: string + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([a-z0-9]|-[a-z0-9])*$ + examples: + - acme v1organizationsUpdateOrganization: description: For update messages ensure the indexes are same as the base model itself. @@ -10730,6 +11534,16 @@ components: type: string examples: - industry: technology + slug: + description: DNS-safe slug for dynamic redirect URI resolution. + Lowercase alphanumeric and hyphens, 1-63 chars, must start and end + with alphanumeric, unique per environment. + type: string + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([a-z0-9]|-[a-z0-9])*$ + examples: + - acme v1rolesCreateOrganizationRole: type: object properties: diff --git a/src/configs/sidebar.config.ts b/src/configs/sidebar.config.ts index f3d8381e3..08188defa 100644 --- a/src/configs/sidebar.config.ts +++ b/src/configs/sidebar.config.ts @@ -51,6 +51,7 @@ export const sidebar = [ 'authenticate/manage-organizations/remove-users-from-organization', 'authenticate/manage-users-orgs/delete-users-and-organizations', 'authenticate/fsa/user-management-settings', + 'authenticate/manage-organizations/organization-session-policy', 'authenticate/manage-users-orgs/hosted-widgets', ], }, diff --git a/src/content/docs/authenticate/fsa/manage-session.mdx b/src/content/docs/authenticate/fsa/manage-session.mdx index 5646fc68a..c563eeded 100644 --- a/src/content/docs/authenticate/fsa/manage-session.mdx +++ b/src/content/docs/authenticate/fsa/manage-session.mdx @@ -19,6 +19,9 @@ seeAlso: - title: "Preserve destination post login" icon: "book" url: "/guides/user-auth/preserve-intended-destination/" + - title: "Organization session policy" + icon: "book" + url: "/authenticate/manage-organizations/organization-session-policy/" --- import { @@ -660,3 +663,9 @@ This guide shows you how to store these tokens securely with encryption and prop Your application continuously validates the access token for each incoming request. When the token is valid, the user's session remains active. If the access token expires, your middleware transparently refreshes it using the stored refresh token—users never notice this happening. If the refresh token itself expires or becomes invalid, users are prompted to sign in again. + +## Organization session policy + +Enterprise customers sometimes require session durations that differ from your application defaults. Scalekit lets you set a custom session policy per organization — controlling absolute timeout and idle timeout independently — while always applying the stricter of the two values at session creation. + +[Learn how to configure organization session policies →](/authenticate/manage-organizations/organization-session-policy/) diff --git a/src/content/docs/authenticate/manage-organizations/organization-session-policy.mdx b/src/content/docs/authenticate/manage-organizations/organization-session-policy.mdx new file mode 100644 index 000000000..14b8f3efe --- /dev/null +++ b/src/content/docs/authenticate/manage-organizations/organization-session-policy.mdx @@ -0,0 +1,308 @@ +--- +title: "Organization session policy" +description: "Override application-level session timeouts for specific organizations with custom absolute and idle session policies" +tags: [organizations, session, policy, timeout, security] +sidebar: + label: "Organization session policy" +tableOfContents: true +prev: + label: "User management settings" + link: "/authenticate/fsa/user-management-settings/" +next: + label: "Hosted UI widgets" + link: "/authenticate/manage-users-orgs/hosted-widgets/" +head: + - tag: style + content: | + .sl-markdown-content h2 { + font-size: var(--sl-text-xl); + } +--- + +import { Aside, Tabs, TabItem } from '@astrojs/starlight/components'; + +By default, all organizations inherit the session policy configured at the application level — covering absolute session duration and idle timeout. When an enterprise customer requires stricter or different session controls than your application defaults, you can set a custom session policy on a per-organization basis. + +Scalekit always enforces the **stricter of the two** (application vs. organization) at session creation time, so organization policies can only tighten — not relax — your application-level defaults. + +## Prerequisites + +Organization-level session policies are controlled by the `session_policy` feature flag. Enable it on the organization before applying a custom policy. + + + + +```javascript +await scalekit.organization.updateOrganizationSettings('org_12345', { + features: [{ name: 'session_policy', enabled: true }], +}); +``` + + + + +```python +scalekit_client.organization.update_organization_settings( + organization_id='org_12345', + settings=[{'name': 'session_policy', 'enabled': True}], +) +``` + + + + +```go +_, err := scalekitClient.Organization().UpdateOrganizationSettings(ctx, "org_12345", + scalekit.OrganizationSettings{ + Features: []scalekit.Feature{ + {Name: "session_policy", Enabled: true}, + }, + }, +) +if err != nil { + log.Fatal(err) +} +``` + + + + +```java +import com.scalekit.grpc.scalekit.v1.organizations.OrganizationSettingsFeature; +import java.util.List; + +scalekitClient.organizations().updateOrganizationSettings( + "org_12345", + List.of(OrganizationSettingsFeature.newBuilder() + .setName("session_policy") + .setEnabled(true) + .build()) +); +``` + + + + +## Session policy fields + +| Field | Description | +|---|---| +| `policySource` | `APPLICATION` (inherit defaults) or `CUSTOM` (use per-org values) | +| `absoluteSessionTimeout` | Maximum session lifetime regardless of activity | +| `absoluteSessionTimeoutUnit` | Unit for absolute timeout: `MINUTES`, `HOURS`, or `DAYS` | +| `idleSessionTimeoutEnabled` | Whether idle timeout is active for this organization | +| `idleSessionTimeout` | Time after which an idle session expires | +| `idleSessionTimeoutUnit` | Unit for idle timeout: `MINUTES`, `HOURS`, or `DAYS` | + + + +## Get the current session policy + +Retrieve the active session policy for an organization to display it in your settings UI or audit the current configuration. + + + + +```javascript +const policy = await scalekit.organization.getOrganizationSessionPolicy('org_12345'); + +// policySource: 1 = APPLICATION (inheriting defaults), 2 = CUSTOM (org-specific values active) +console.log('Policy source:', policy.policySource); +console.log('Absolute timeout (minutes):', policy.absoluteSessionTimeout); +console.log('Idle timeout enabled:', policy.idleSessionTimeoutEnabled); +``` + + + + +```python +from scalekit.v1.organizations.organizations_pb2 import SessionPolicyType + +response, _ = scalekit_client.organization.get_organization_session_policy('org_12345') +policy = response.policy + +if policy.policy_source == SessionPolicyType.CUSTOM: + print('Absolute timeout (minutes):', policy.absolute_session_timeout.value) + print('Idle timeout enabled:', policy.idle_session_timeout_enabled.value) +``` + + + + +```go +policy, err := scalekitClient.Organization().GetOrganizationSessionPolicy(ctx, "org_12345") +if err != nil { + log.Fatal(err) +} + +if policy.PolicySource == scalekit.SessionPolicySourceCustom { + fmt.Println("Absolute timeout (minutes):", policy.AbsoluteSessionTimeout.GetValue()) + fmt.Println("Idle timeout enabled:", policy.IdleSessionTimeoutEnabled.GetValue()) +} +``` + + + + +```java +import com.scalekit.grpc.scalekit.v1.organizations.OrganizationSessionPolicySettings; +import com.scalekit.grpc.scalekit.v1.organizations.SessionPolicyType; + +OrganizationSessionPolicySettings policy = + scalekitClient.organizations().getOrganizationSessionPolicy("org_12345"); + +if (policy.getPolicySource() == SessionPolicyType.CUSTOM) { + System.out.println("Absolute timeout (minutes): " + policy.getAbsoluteSessionTimeout().getValue()); + System.out.println("Idle timeout enabled: " + policy.getIdleSessionTimeoutEnabled().getValue()); +} +``` + + + + +## Set a custom session policy + +Apply a custom policy when an organization requires different session durations than your application defaults. + + + + +```javascript +const updated = await scalekit.organization.updateOrganizationSessionPolicy('org_12345', { + policySource: 'CUSTOM', + absoluteSessionTimeout: 480, + absoluteSessionTimeoutUnit: 'MINUTES', + idleSessionTimeoutEnabled: true, + idleSessionTimeout: 60, + idleSessionTimeoutUnit: 'MINUTES', +}); + +console.log('Policy updated:', updated.policySource); +``` + + + + +```python +from scalekit.v1.organizations.organizations_pb2 import SessionPolicyType +from scalekit.v1.commons.commons_pb2 import TimeUnit + +response, _ = scalekit_client.organization.update_organization_session_policy( + organization_id='org_12345', + policy_source=SessionPolicyType.CUSTOM, + absolute_session_timeout=480, + absolute_session_timeout_unit=TimeUnit.MINUTES, + idle_session_timeout_enabled=True, + idle_session_timeout=60, + idle_session_timeout_unit=TimeUnit.MINUTES, +) + +print('Policy updated:', response.policy.policy_source) +``` + + + + +```go +timeout := int32(480) +idleTimeout := int32(60) +idleEnabled := true + +updated, err := scalekitClient.Organization().UpdateOrganizationSessionPolicy(ctx, "org_12345", scalekit.OrganizationSessionPolicy{ + PolicySource: scalekit.SessionPolicySourceCustom, + AbsoluteSessionTimeout: &timeout, + AbsoluteSessionTimeoutUnit: scalekit.TimeUnitMinutes, + IdleSessionTimeoutEnabled: &idleEnabled, + IdleSessionTimeout: &idleTimeout, + IdleSessionTimeoutUnit: scalekit.TimeUnitMinutes, +}) +if err != nil { + log.Fatal(err) +} + +fmt.Println("Policy updated:", updated.PolicySource) +``` + + + + +```java +import com.google.protobuf.Int32Value; +import com.google.protobuf.BoolValue; +import com.scalekit.grpc.scalekit.v1.commons.TimeUnit; +import com.scalekit.grpc.scalekit.v1.organizations.OrganizationSessionPolicySettings; +import com.scalekit.grpc.scalekit.v1.organizations.SessionPolicyType; + +OrganizationSessionPolicySettings policy = OrganizationSessionPolicySettings.newBuilder() + .setPolicySource(SessionPolicyType.CUSTOM) + .setAbsoluteSessionTimeout(Int32Value.of(480)) + .setAbsoluteSessionTimeoutUnit(TimeUnit.MINUTES) + .setIdleSessionTimeoutEnabled(BoolValue.of(true)) + .setIdleSessionTimeout(Int32Value.of(60)) + .setIdleSessionTimeoutUnit(TimeUnit.MINUTES) + .build(); + +OrganizationSessionPolicySettings updated = + scalekitClient.organizations().updateOrganizationSessionPolicy("org_12345", policy); + +System.out.println("Policy updated: " + updated.getPolicySource()); +``` + + + + +## Revert to application defaults + +Remove a custom policy and restore the organization to the application-level session settings. + + + + +```javascript +await scalekit.organization.updateOrganizationSessionPolicy('org_12345', { + policySource: 'APPLICATION', +}); +``` + + + + +```python +from scalekit.v1.organizations.organizations_pb2 import SessionPolicyType + +scalekit_client.organization.update_organization_session_policy( + organization_id='org_12345', + policy_source=SessionPolicyType.APPLICATION, +) +``` + + + + +```go +_, err := scalekitClient.Organization().UpdateOrganizationSessionPolicy(ctx, "org_12345", scalekit.OrganizationSessionPolicy{ + PolicySource: scalekit.SessionPolicySourceApplication, +}) +if err != nil { + log.Fatal(err) +} +``` + + + + +```java +import com.scalekit.grpc.scalekit.v1.organizations.OrganizationSessionPolicySettings; +import com.scalekit.grpc.scalekit.v1.organizations.SessionPolicyType; + +OrganizationSessionPolicySettings policy = OrganizationSessionPolicySettings.newBuilder() + .setPolicySource(SessionPolicyType.APPLICATION) + .build(); + +scalekitClient.organizations().updateOrganizationSessionPolicy("org_12345", policy); +``` + + +