@@ -654,6 +654,9 @@ sso_link = descope_client.mgmt.tenant.generate_sso_configuration_link(
654654 expire_time = 21600 ,
655655 actor_id = " my-admin-actor-id" ,
656656)
657+
658+ # Revoke a previously generated SSO configuration link
659+ descope_client.mgmt.tenant.revoke_sso_configuration_link(tenant_id = " my-custom-id" )
657660```
658661
659662### Manage Users
@@ -794,6 +797,29 @@ users = users_resp["users"]
794797users_history_resp = descope_client.mgmt.user.history([" user-id-1" , " user-id-2" ])
795798 for user_history in users_history_resp:
796799 # Do something
800+
801+ # Delete multiple users at once. IMPORTANT: This action is irreversible. Use carefully.
802+ descope_client.mgmt.user.delete_batch([" <user-id-1>" , " <user-id-2>" ])
803+
804+ # Import users from an external source (users/hashes are JSON-encoded bytes)
805+ descope_client.mgmt.user.import_users(source = " auth0" , users = b ' {"users":[]}' , dryrun = True )
806+
807+ # Manage custom user attributes
808+ descope_client.mgmt.user.create_custom_attribute(name = " favorite_color" , display_name = " Favorite Color" , type = " text" )
809+ descope_client.mgmt.user.load_custom_attributes()
810+ descope_client.mgmt.user.delete_custom_attribute(" favorite_color" )
811+
812+ # Manage a user's passkeys (WebAuthn devices)
813+ passkeys = descope_client.mgmt.user.list_passkeys(" <login-id>" )
814+ descope_client.mgmt.user.delete_passkey(" <login-id>" , " <credential-id>" )
815+
816+ # Manage trusted devices
817+ devices = descope_client.mgmt.user.list_trusted_devices([" <login-id>" ])
818+ descope_client.mgmt.user.remove_trusted_device(" <login-id>" , [" <device-id>" ])
819+
820+ # Update a user's recovery email / phone
821+ descope_client.mgmt.user.update_recovery_email(" <login-id>" , " recovery@example.com" , verified = True )
822+ descope_client.mgmt.user.update_recovery_phone(" <login-id>" , " +15555555555" , verified = True )
797823```
798824
799825#### Set or Expire User Password
@@ -814,6 +840,20 @@ descope_client.mgmt.user.set_active_password('<login-id>', '<some-password>');
814840descope_client.mgmt.user.expirePassword(' <login-id>' );
815841```
816842
843+ You can also read and configure the password policy settings, at the project level or per tenant:
844+
845+ ``` python
846+ # Get password settings (project-level when tenant_id is omitted)
847+ settings = descope_client.mgmt.password.get_settings()
848+ tenant_settings = descope_client.mgmt.password.get_settings(tenant_id = " my-tenant-id" )
849+
850+ # Configure password settings for a tenant
851+ descope_client.mgmt.password.configure_settings(
852+ tenant_id = " my-tenant-id" ,
853+ settings = {" minLength" : 8 , " lowercase" : True , " uppercase" : True , " number" : True },
854+ )
855+ ```
856+
817857### Manage Access Keys
818858
819859You can create, update, delete or load access keys, as well as search according to filters:
@@ -866,6 +906,14 @@ descope_client.mgmt.access_key.activate("key-id")
866906
867907# Access key deletion cannot be undone. Use carefully.
868908descope_client.mgmt.access_key.delete(" key-id" )
909+
910+ # Rotate an access key - the previous cleartext is invalidated and a new one returned.
911+ rotate_resp = descope_client.mgmt.access_key.rotate(" key-id" )
912+
913+ # Activate, deactivate or delete multiple access keys at once.
914+ descope_client.mgmt.access_key.activate_batch([" key-id-1" , " key-id-2" ])
915+ descope_client.mgmt.access_key.deactivate_batch([" key-id-1" , " key-id-2" ])
916+ descope_client.mgmt.access_key.delete_batch([" key-id-1" , " key-id-2" ])
869917```
870918
871919Exchange the access key and provide optional access key login options:
@@ -1302,6 +1350,15 @@ refresh_jwt = descope_client.mgmt.jwt.impersonate(
13021350 custom_claims = {" key1" :" value1" },
13031351 tenant_id = " <One of the tenants the impersonated user belongs to>"
13041352)
1353+
1354+ # Impersonate with step-up, returning a fresh session and refresh JWT pair
1355+ jwt_resp = descope_client.mgmt.jwt.impersonate_stepup(
1356+ impersonator_id = " <Login ID impersonator>" ,
1357+ login_id = " <Login ID of impersonated person>" ,
1358+ validate_consent = True ,
1359+ custom_claims = {" key1" : " value1" },
1360+ tenant_id = " <One of the tenants the impersonated user belongs to>" ,
1361+ )
13051362```
13061363
13071364# Note 1: The generate code/link functions, work only for test users, will not work for regular users.
@@ -1345,6 +1402,16 @@ await descopeClient.management.audit.create_event(
13451402)
13461403```
13471404
1405+ You can create an audit webhook to stream audit events to an external endpoint:
1406+
1407+ ``` python
1408+ descope_client.mgmt.audit.create_audit_webhook(
1409+ name = " my-webhook" ,
1410+ url = " https://example.com/audit" ,
1411+ headers = {" Authorization" : " Bearer <token>" },
1412+ )
1413+ ```
1414+
13481415### Manage FGA (Fine-grained Authorization)
13491416
13501417Descope supports full relation based access control (ReBAC) using a zanzibar like schema and operations.
@@ -1437,6 +1504,17 @@ When the `fga_cache_url` is configured, the following FGA methods will automatic
14371504
14381505Other FGA operations like ` load_schema ` will continue to use the standard Descope API endpoints.
14391506
1507+ You can also validate a schema with a dry run, and load the mappable schema and resources for a tenant:
1508+
1509+ ``` python
1510+ # Validate a schema without applying it
1511+ descope_client.mgmt.fga.save_schema_dryrun(schema)
1512+
1513+ # Load the mappable schema / resources for a tenant
1514+ descope_client.mgmt.fga.load_mappable_schema(" tenant-id" , resources_limit = 100 )
1515+ descope_client.mgmt.fga.load_mappable_resources(" tenant-id" , [{" query" : " doc" }], resources_limit = 50 )
1516+ ```
1517+
14401518### Manage Project
14411519
14421520You can change the project name, as well as clone the current project to
@@ -1467,6 +1545,22 @@ export = descope_client.mgmt.project.export_project()
14671545descope_client.mgmt.project.import_project(export)
14681546```
14691547
1548+ You can also work with project snapshots and delete a project.
1549+
1550+ ``` python
1551+ # Export a snapshot of the project (optionally for a specific environment)
1552+ snapshot = descope_client.mgmt.project.export_snapshot()
1553+
1554+ # Validate a snapshot before importing it
1555+ validation = descope_client.mgmt.project.validate_snapshot(snapshot[" files" ])
1556+
1557+ # Import a previously exported snapshot
1558+ descope_client.mgmt.project.import_snapshot(snapshot[" files" ])
1559+
1560+ # Delete the current project. IMPORTANT: This action is irreversible. Use carefully.
1561+ descope_client.mgmt.project.delete()
1562+ ```
1563+
14701564### Manage SSO Applications
14711565
14721566You can create, update, delete or load sso applications:
@@ -1522,6 +1616,25 @@ apps_resp = descope_client.mgmt.sso_application.load_all()
15221616apps = apps_resp[" apps" ]
15231617 for app in apps:
15241618 # Do something
1619+
1620+ # Create / update a WS-Fed SSO application
1621+ descope_client.mgmt.sso_application.create_wsfed_application(
1622+ name = " My WS-Fed app" ,
1623+ login_page_url = " http://dummy.com" ,
1624+ realm = " urn:my-realm" ,
1625+ reply_url = " http://dummy.com/reply" ,
1626+ )
1627+ descope_client.mgmt.sso_application.update_wsfed_application(
1628+ id = " my-custom-id" ,
1629+ name = " My WS-Fed app" ,
1630+ login_page_url = " http://dummy.com" ,
1631+ realm = " urn:my-realm" ,
1632+ reply_url = " http://dummy.com/reply" ,
1633+ )
1634+
1635+ # Get or rotate the SSO application secret
1636+ secret = descope_client.mgmt.sso_application.get_application_secret(" my-custom-id" )
1637+ new_secret = descope_client.mgmt.sso_application.rotate_application_secret(" my-custom-id" )
15251638```
15261639
15271640### Manage Outbound Applications
@@ -1894,6 +2007,94 @@ new_secret = descope_client.mgmt.engine.rotate_secret(engine_id)["secret"]
18942007descope_client.mgmt.engine.delete(engine_id)
18952008```
18962009
2010+ ### Manage Lists
2011+
2012+ Lists let you maintain reusable allow/deny collections of IPs, text values or arbitrary JSON.
2013+ The lists client is available as ` descope_client.mgmt.list ` .
2014+
2015+ ``` python
2016+ # Create a list (list_type is one of "ips", "texts" or "json")
2017+ my_list = descope_client.mgmt.list.create(
2018+ name = " blocked-ips" ,
2019+ list_type = " ips" ,
2020+ description = " IPs to block" ,
2021+ data = [" 1.2.3.4" ],
2022+ )
2023+ list_id = my_list[" id" ]
2024+
2025+ # Update / load / delete
2026+ descope_client.mgmt.list.update(list_id, name = " blocked-ips" , description = " updated" )
2027+ descope_client.mgmt.list.load(list_id)
2028+ descope_client.mgmt.list.load_by_name(" blocked-ips" )
2029+ descope_client.mgmt.list.load_all()
2030+ descope_client.mgmt.list.delete(list_id)
2031+
2032+ # Bulk import lists
2033+ descope_client.mgmt.list.import_lists([{" name" : " blocked-ips" , " type" : " ips" , " data" : [" 1.2.3.4" ]}])
2034+
2035+ # IP list operations
2036+ descope_client.mgmt.list.add_ips(list_id, [" 5.6.7.8" ])
2037+ descope_client.mgmt.list.remove_ips(list_id, [" 1.2.3.4" ])
2038+ is_blocked = descope_client.mgmt.list.check_ip(list_id, " 5.6.7.8" )
2039+
2040+ # Text list operations
2041+ descope_client.mgmt.list.add_texts(list_id, [" foo" ])
2042+ descope_client.mgmt.list.remove_texts(list_id, [" foo" ])
2043+ has_text = descope_client.mgmt.list.check_text(list_id, " foo" )
2044+
2045+ # Remove all entries from a list
2046+ descope_client.mgmt.list.clear(list_id)
2047+ ```
2048+
2049+ ### Manage Scope and Claim Mappings
2050+
2051+ Scope/claim mappings control which claims are emitted for a given OAuth scope.
2052+
2053+ ``` python
2054+ # Get the current mappings
2055+ mappings = descope_client.mgmt.scope_claim_mapping.get()
2056+
2057+ # Replace all mappings
2058+ descope_client.mgmt.scope_claim_mapping.set(
2059+ [{" scope" : " profile" , " claims" : {" name" : " name" }, " description" : " profile scope" }]
2060+ )
2061+
2062+ # Delete all mappings
2063+ descope_client.mgmt.scope_claim_mapping.delete()
2064+ ```
2065+
2066+ ### Manage Third Party Applications
2067+
2068+ You can create, update, delete or load third party (OIDC) applications, manage their
2069+ secrets and the consents granted to them.
2070+
2071+ ``` python
2072+ # Create a third party application
2073+ app = descope_client.mgmt.third_party_application.create(
2074+ name = " My App" ,
2075+ login_page_url = " http://dummy.com" ,
2076+ approved_callback_urls = [" http://dummy.com/callback" ],
2077+ )
2078+ app_id = app[" id" ]
2079+
2080+ # Update / patch / load / delete
2081+ descope_client.mgmt.third_party_application.update(app_id, name = " My App" , login_page_url = " http://dummy.com" )
2082+ descope_client.mgmt.third_party_application.patch(app_id, name = " Renamed App" )
2083+ descope_client.mgmt.third_party_application.load(app_id)
2084+ descope_client.mgmt.third_party_application.load_all()
2085+ descope_client.mgmt.third_party_application.delete(app_id)
2086+ descope_client.mgmt.third_party_application.delete_batch([app_id])
2087+
2088+ # Manage the application secret
2089+ descope_client.mgmt.third_party_application.get_secret(app_id)
2090+ descope_client.mgmt.third_party_application.rotate_secret(app_id)
2091+
2092+ # Manage consents
2093+ descope_client.mgmt.third_party_application.search_consents(app_id = app_id)
2094+ descope_client.mgmt.third_party_application.delete_consents(app_id = app_id)
2095+ descope_client.mgmt.third_party_application.delete_tenant_consents(" tenant-id" )
2096+ ```
2097+
18972098### Utils for your end to end (e2e) tests and integration tests
18982099
18992100To ease your e2e tests, we exposed dedicated management methods,
0 commit comments