From 70122181e6bc5cb13cac1010f1dd0f74be70a193 Mon Sep 17 00:00:00 2001 From: swaroopakkineni Date: Tue, 17 Feb 2026 10:03:53 -1000 Subject: [PATCH 1/7] base python sdk for fga --- src/workos/fga.py | 12 +++++ .../fixtures/mock_authorization_resource.py | 54 +++++++++++++++++++ tests/utils/fixtures/mock_role_assignment.py | 46 ++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 tests/utils/fixtures/mock_authorization_resource.py create mode 100644 tests/utils/fixtures/mock_role_assignment.py diff --git a/src/workos/fga.py b/src/workos/fga.py index 2c76a320..03c97357 100644 --- a/src/workos/fga.py +++ b/src/workos/fga.py @@ -1,5 +1,17 @@ +""" +DEPRECATED: This module is deprecated and will be removed in a future version. +Please use workos.authorization instead for Fine-Grained Authorization (FGA) functionality. + +See authorization.py for the new resource-based FGA APIs: +- get_resource, create_resource, update_resource, delete_resource, list_resources +- get_resource_by_external_id, update_resource_by_external_id, delete_resource_by_external_id +- check, assign_role, remove_role, list_role_assignments, remove_role_assignment +- list_resources_for_membership, list_memberships_for_resource, list_memberships_for_resource_by_external_id +""" + import json from typing import Any, Mapping, Optional, Protocol, Sequence + from workos.types.fga import ( CheckOperation, CheckResponse, diff --git a/tests/utils/fixtures/mock_authorization_resource.py b/tests/utils/fixtures/mock_authorization_resource.py new file mode 100644 index 00000000..d8f6beb8 --- /dev/null +++ b/tests/utils/fixtures/mock_authorization_resource.py @@ -0,0 +1,54 @@ +"""Mock fixture for AuthorizationResource used in testing new FGA APIs. + +This fixture represents the new organization-scoped authorization resource model +used in the Advanced FGA APIs, distinct from the legacy warrant-based resources. +""" + +from typing import Optional + + +class MockAuthorizationResource: + """Mock authorization resource for testing the new FGA resource-based APIs. + + Attributes: + id: Internal WorkOS resource ID. + external_id: Customer-provided external identifier for the resource. + name: Human-readable name for the resource. + description: Optional description of the resource. + resource_type_slug: The type of resource (e.g., "document", "folder"). + organization_id: The organization this resource belongs to. + parent_resource_id: Optional parent resource ID for hierarchical resources. + """ + + def __init__( + self, + id: str = "authz_resource_01HXYZ123ABC456DEF789ABC", + external_id: str = "doc-456", + name: str = "Q4 Budget Report", + description: Optional[str] = "Financial report for Q4 2025", + resource_type_slug: str = "document", + organization_id: str = "org_01HXYZ123ABC456DEF789ABC", + parent_resource_id: Optional[str] = None, + ): + self.id = id + self.external_id = external_id + self.name = name + self.description = description + self.resource_type_slug = resource_type_slug + self.organization_id = organization_id + self.parent_resource_id = parent_resource_id + + def dict(self) -> dict: + """Return the resource as a dictionary matching API response format.""" + return { + "object": "authorization_resource", + "id": self.id, + "external_id": self.external_id, + "name": self.name, + "description": self.description, + "resource_type_slug": self.resource_type_slug, + "organization_id": self.organization_id, + "parent_resource_id": self.parent_resource_id, + "created_at": "2024-01-15T09:30:00.000Z", + "updated_at": "2024-01-15T09:30:00.000Z", + } diff --git a/tests/utils/fixtures/mock_role_assignment.py b/tests/utils/fixtures/mock_role_assignment.py new file mode 100644 index 00000000..51819154 --- /dev/null +++ b/tests/utils/fixtures/mock_role_assignment.py @@ -0,0 +1,46 @@ +"""Mock fixture for RoleAssignment used in testing new FGA APIs. + +This fixture represents role assignments that grant a role to an organization +membership on a specific resource. +""" + + +class MockRoleAssignment: + """Mock role assignment for testing the new FGA role assignment APIs. + + Attributes: + id: Internal WorkOS role assignment ID. + role_slug: The slug of the role being assigned (e.g., "editor", "viewer"). + resource_id: The internal ID of the resource the role is assigned on. + resource_external_id: The external ID of the resource. + resource_type_slug: The type of resource (e.g., "document", "folder"). + """ + + def __init__( + self, + id: str = "role_assignment_01HXYZ123ABC456DEF789ABC", + role_slug: str = "editor", + resource_id: str = "resource_01HXYZ123ABC456DEF789XYZ", + resource_external_id: str = "doc-123", + resource_type_slug: str = "document", + ): + self.id = id + self.role_slug = role_slug + self.resource_id = resource_id + self.resource_external_id = resource_external_id + self.resource_type_slug = resource_type_slug + + def dict(self) -> dict: + """Return the role assignment as a dictionary matching API response format.""" + return { + "object": "role_assignment", + "id": self.id, + "role": {"slug": self.role_slug}, + "resource": { + "id": self.resource_id, + "external_id": self.resource_external_id, + "resource_type_slug": self.resource_type_slug, + }, + "created_at": "2024-01-15T09:30:00.000Z", + "updated_at": "2024-01-15T09:30:00.000Z", + } From baf69bba7307d32d871ef7f1aed52882f04d7f69 Mon Sep 17 00:00:00 2001 From: swaroopakkineni Date: Tue, 17 Feb 2026 10:08:09 -1000 Subject: [PATCH 2/7] cleanup --- src/workos/fga.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/workos/fga.py b/src/workos/fga.py index 03c97357..5ce39abb 100644 --- a/src/workos/fga.py +++ b/src/workos/fga.py @@ -1,12 +1,6 @@ """ -DEPRECATED: This module is deprecated and will be removed in a future version. -Please use workos.authorization instead for Fine-Grained Authorization (FGA) functionality. - -See authorization.py for the new resource-based FGA APIs: -- get_resource, create_resource, update_resource, delete_resource, list_resources -- get_resource_by_external_id, update_resource_by_external_id, delete_resource_by_external_id -- check, assign_role, remove_role, list_role_assignments, remove_role_assignment -- list_resources_for_membership, list_memberships_for_resource, list_memberships_for_resource_by_external_id +DEPRECATED: This module is deprecated, use the Authorization module instead. +See src/workos/authorization.py """ import json From 967e5405ad81bca8879ef735b1948528d7cd3623 Mon Sep 17 00:00:00 2001 From: swaroopakkineni Date: Tue, 17 Feb 2026 10:25:24 -1000 Subject: [PATCH 3/7] lol --- src/workos/types/authorization/__init__.py | 4 ++ .../authorization/authorization_resource.py | 21 ++++++++ .../fixtures/mock_authorization_resource.py | 54 +++++-------------- 3 files changed, 39 insertions(+), 40 deletions(-) create mode 100644 src/workos/types/authorization/authorization_resource.py diff --git a/src/workos/types/authorization/__init__.py b/src/workos/types/authorization/__init__.py index 609a4f2d..263cddf3 100644 --- a/src/workos/types/authorization/__init__.py +++ b/src/workos/types/authorization/__init__.py @@ -1,3 +1,7 @@ +from workos.types.authorization.authorization_resource import ( + AuthorizationResource, + AuthorizationResourceList, +) from workos.types.authorization.environment_role import ( EnvironmentRole, EnvironmentRoleList, diff --git a/src/workos/types/authorization/authorization_resource.py b/src/workos/types/authorization/authorization_resource.py new file mode 100644 index 00000000..ab3cef5e --- /dev/null +++ b/src/workos/types/authorization/authorization_resource.py @@ -0,0 +1,21 @@ +from typing import Literal, Optional, Sequence + +from workos.types.workos_model import WorkOSModel + + +class AuthorizationResource(WorkOSModel): + object: Literal["authorization_resource"] + id: str + external_id: str + name: str + description: Optional[str] = None + resource_type_slug: str + organization_id: str + parent_resource_id: Optional[str] = None + created_at: str + updated_at: str + + +class AuthorizationResourceList(WorkOSModel): + object: Literal["list"] + data: Sequence[AuthorizationResource] diff --git a/tests/utils/fixtures/mock_authorization_resource.py b/tests/utils/fixtures/mock_authorization_resource.py index d8f6beb8..647a8782 100644 --- a/tests/utils/fixtures/mock_authorization_resource.py +++ b/tests/utils/fixtures/mock_authorization_resource.py @@ -1,25 +1,9 @@ -"""Mock fixture for AuthorizationResource used in testing new FGA APIs. - -This fixture represents the new organization-scoped authorization resource model -used in the Advanced FGA APIs, distinct from the legacy warrant-based resources. -""" - from typing import Optional +from workos.types.authorization.authorization_resource import AuthorizationResource -class MockAuthorizationResource: - """Mock authorization resource for testing the new FGA resource-based APIs. - - Attributes: - id: Internal WorkOS resource ID. - external_id: Customer-provided external identifier for the resource. - name: Human-readable name for the resource. - description: Optional description of the resource. - resource_type_slug: The type of resource (e.g., "document", "folder"). - organization_id: The organization this resource belongs to. - parent_resource_id: Optional parent resource ID for hierarchical resources. - """ +class MockAuthorizationResource(AuthorizationResource): def __init__( self, id: str = "authz_resource_01HXYZ123ABC456DEF789ABC", @@ -30,25 +14,15 @@ def __init__( organization_id: str = "org_01HXYZ123ABC456DEF789ABC", parent_resource_id: Optional[str] = None, ): - self.id = id - self.external_id = external_id - self.name = name - self.description = description - self.resource_type_slug = resource_type_slug - self.organization_id = organization_id - self.parent_resource_id = parent_resource_id - - def dict(self) -> dict: - """Return the resource as a dictionary matching API response format.""" - return { - "object": "authorization_resource", - "id": self.id, - "external_id": self.external_id, - "name": self.name, - "description": self.description, - "resource_type_slug": self.resource_type_slug, - "organization_id": self.organization_id, - "parent_resource_id": self.parent_resource_id, - "created_at": "2024-01-15T09:30:00.000Z", - "updated_at": "2024-01-15T09:30:00.000Z", - } + super().__init__( + object="authorization_resource", + id=id, + external_id=external_id, + name=name, + description=description, + resource_type_slug=resource_type_slug, + organization_id=organization_id, + parent_resource_id=parent_resource_id, + created_at="2024-01-15T09:30:00.000Z", + updated_at="2024-01-15T09:30:00.000Z", + ) From 6c82188661777a94eaf2b0841494140ea3632d9c Mon Sep 17 00:00:00 2001 From: swaroopakkineni Date: Tue, 17 Feb 2026 10:36:10 -1000 Subject: [PATCH 4/7] lol --- src/workos/types/authorization/authorization_resource.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/workos/types/authorization/authorization_resource.py b/src/workos/types/authorization/authorization_resource.py index ab3cef5e..d6121891 100644 --- a/src/workos/types/authorization/authorization_resource.py +++ b/src/workos/types/authorization/authorization_resource.py @@ -1,5 +1,6 @@ from typing import Literal, Optional, Sequence +from workos.types.list_resource import ListMetadata from workos.types.workos_model import WorkOSModel @@ -19,3 +20,4 @@ class AuthorizationResource(WorkOSModel): class AuthorizationResourceList(WorkOSModel): object: Literal["list"] data: Sequence[AuthorizationResource] + list_metadata: ListMetadata From cc65ddaef44f4c041dba07d10d9b33e1541c7472 Mon Sep 17 00:00:00 2001 From: swaroopakkineni Date: Tue, 17 Feb 2026 10:36:37 -1000 Subject: [PATCH 5/7] lol --- src/workos/fga.py | 1 - src/workos/types/authorization/authorization_resource.py | 1 - 2 files changed, 2 deletions(-) diff --git a/src/workos/fga.py b/src/workos/fga.py index 5ce39abb..645a5662 100644 --- a/src/workos/fga.py +++ b/src/workos/fga.py @@ -5,7 +5,6 @@ import json from typing import Any, Mapping, Optional, Protocol, Sequence - from workos.types.fga import ( CheckOperation, CheckResponse, diff --git a/src/workos/types/authorization/authorization_resource.py b/src/workos/types/authorization/authorization_resource.py index d6121891..f4a35003 100644 --- a/src/workos/types/authorization/authorization_resource.py +++ b/src/workos/types/authorization/authorization_resource.py @@ -3,7 +3,6 @@ from workos.types.list_resource import ListMetadata from workos.types.workos_model import WorkOSModel - class AuthorizationResource(WorkOSModel): object: Literal["authorization_resource"] id: str From b78934e4a87bb67ef214cfe3ec21c9f51fa82433 Mon Sep 17 00:00:00 2001 From: swaroopakkineni Date: Tue, 17 Feb 2026 10:43:28 -1000 Subject: [PATCH 6/7] lol --- src/workos/types/authorization/__init__.py | 6 +++++ .../types/authorization/role_assignment.py | 26 +++++++++++++++++++ .../fixtures/mock_authorization_resource.py | 2 +- tests/utils/fixtures/mock_role_assignment.py | 18 ------------- 4 files changed, 33 insertions(+), 19 deletions(-) create mode 100644 src/workos/types/authorization/role_assignment.py diff --git a/src/workos/types/authorization/__init__.py b/src/workos/types/authorization/__init__.py index 263cddf3..a405ec84 100644 --- a/src/workos/types/authorization/__init__.py +++ b/src/workos/types/authorization/__init__.py @@ -16,3 +16,9 @@ Role, RoleList, ) +from workos.types.authorization.role_assignment import ( + RoleAssignment, + RoleAssignmentList, + RoleAssignmentResource, + RoleAssignmentRole, +) diff --git a/src/workos/types/authorization/role_assignment.py b/src/workos/types/authorization/role_assignment.py new file mode 100644 index 00000000..55df0550 --- /dev/null +++ b/src/workos/types/authorization/role_assignment.py @@ -0,0 +1,26 @@ +from typing import Literal, Optional, Sequence + +from workos.types.list_resource import ListMetadata +from workos.types.workos_model import WorkOSModel + +class RoleAssignmentRole(WorkOSModel): + slug: str + +class RoleAssignmentResource(WorkOSModel): + id: str + external_id: str + resource_type_slug: str + +class RoleAssignment(WorkOSModel): + object: Literal["role_assignment"] + id: str + role: RoleAssignmentRole + resource: RoleAssignmentResource + created_at: str + updated_at: str + + +class RoleAssignmentList(WorkOSModel): + object: Literal["list"] + data: Sequence[RoleAssignment] + list_metadata: ListMetadata diff --git a/tests/utils/fixtures/mock_authorization_resource.py b/tests/utils/fixtures/mock_authorization_resource.py index 647a8782..1c25d35c 100644 --- a/tests/utils/fixtures/mock_authorization_resource.py +++ b/tests/utils/fixtures/mock_authorization_resource.py @@ -10,7 +10,7 @@ def __init__( external_id: str = "doc-456", name: str = "Q4 Budget Report", description: Optional[str] = "Financial report for Q4 2025", - resource_type_slug: str = "document", + resource_type_slug: str = "folder", organization_id: str = "org_01HXYZ123ABC456DEF789ABC", parent_resource_id: Optional[str] = None, ): diff --git a/tests/utils/fixtures/mock_role_assignment.py b/tests/utils/fixtures/mock_role_assignment.py index 51819154..addf5246 100644 --- a/tests/utils/fixtures/mock_role_assignment.py +++ b/tests/utils/fixtures/mock_role_assignment.py @@ -1,21 +1,4 @@ -"""Mock fixture for RoleAssignment used in testing new FGA APIs. - -This fixture represents role assignments that grant a role to an organization -membership on a specific resource. -""" - - class MockRoleAssignment: - """Mock role assignment for testing the new FGA role assignment APIs. - - Attributes: - id: Internal WorkOS role assignment ID. - role_slug: The slug of the role being assigned (e.g., "editor", "viewer"). - resource_id: The internal ID of the resource the role is assigned on. - resource_external_id: The external ID of the resource. - resource_type_slug: The type of resource (e.g., "document", "folder"). - """ - def __init__( self, id: str = "role_assignment_01HXYZ123ABC456DEF789ABC", @@ -31,7 +14,6 @@ def __init__( self.resource_type_slug = resource_type_slug def dict(self) -> dict: - """Return the role assignment as a dictionary matching API response format.""" return { "object": "role_assignment", "id": self.id, From 6f8287918c1681ec3fb663c14e7c145cc5e25aa0 Mon Sep 17 00:00:00 2001 From: swaroopakkineni Date: Tue, 17 Feb 2026 12:40:39 -1000 Subject: [PATCH 7/7] mabe fix --- .../types/authorization/authorization_resource.py | 9 ++++++--- src/workos/types/authorization/role_assignment.py | 11 ++++++++--- src/workos/types/list_metadata.py | 10 ++++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 src/workos/types/list_metadata.py diff --git a/src/workos/types/authorization/authorization_resource.py b/src/workos/types/authorization/authorization_resource.py index f4a35003..e5fefbf4 100644 --- a/src/workos/types/authorization/authorization_resource.py +++ b/src/workos/types/authorization/authorization_resource.py @@ -1,8 +1,11 @@ -from typing import Literal, Optional, Sequence +from typing import TYPE_CHECKING, Literal, Optional, Sequence -from workos.types.list_resource import ListMetadata from workos.types.workos_model import WorkOSModel +if TYPE_CHECKING: + from workos.types.list_resource import ListMetadata + + class AuthorizationResource(WorkOSModel): object: Literal["authorization_resource"] id: str @@ -19,4 +22,4 @@ class AuthorizationResource(WorkOSModel): class AuthorizationResourceList(WorkOSModel): object: Literal["list"] data: Sequence[AuthorizationResource] - list_metadata: ListMetadata + list_metadata: "ListMetadata" diff --git a/src/workos/types/authorization/role_assignment.py b/src/workos/types/authorization/role_assignment.py index 55df0550..13ecad94 100644 --- a/src/workos/types/authorization/role_assignment.py +++ b/src/workos/types/authorization/role_assignment.py @@ -1,16 +1,21 @@ -from typing import Literal, Optional, Sequence +from typing import TYPE_CHECKING, Literal, Sequence -from workos.types.list_resource import ListMetadata from workos.types.workos_model import WorkOSModel +if TYPE_CHECKING: + from workos.types.list_resource import ListMetadata + + class RoleAssignmentRole(WorkOSModel): slug: str + class RoleAssignmentResource(WorkOSModel): id: str external_id: str resource_type_slug: str + class RoleAssignment(WorkOSModel): object: Literal["role_assignment"] id: str @@ -23,4 +28,4 @@ class RoleAssignment(WorkOSModel): class RoleAssignmentList(WorkOSModel): object: Literal["list"] data: Sequence[RoleAssignment] - list_metadata: ListMetadata + list_metadata: "ListMetadata" diff --git a/src/workos/types/list_metadata.py b/src/workos/types/list_metadata.py new file mode 100644 index 00000000..43315678 --- /dev/null +++ b/src/workos/types/list_metadata.py @@ -0,0 +1,10 @@ +from pydantic import BaseModel +from typing import Optional + + +class ListAfterMetadata(BaseModel): + after: Optional[str] = None + + +class ListMetadata(ListAfterMetadata): + before: Optional[str] = None