Service Identities
Methods on this page are called as client.service_identities.<method>(...) where client is either a synchronous Goodmem or asynchronous AsyncGoodmem instance initialized below:
from goodmem import Goodmem
client = Goodmem(base_url='http://localhost:8080', api_key='gm_...')from goodmem import AsyncGoodmem
client = AsyncGoodmem(base_url='http://localhost:8080', api_key='gm_...')Create a service identity
service_identities.create(*, display_name: str, description: str = None, labels: dict[str, str] = None, service_identity_id: str = None) → ServiceIdentityResponse
Creates one production-workload identity owned by the authenticated human. No API key, role, grant, or authentication mapping is created implicitly.
Parameters:
- display_name (
str) — Globally unique, nonblank operator-facing name. - description (
str, optional) — Optional operator description. - labels (
dict[str, str], optional) — Optional labels for organization and filtering. At most 20 entries; keys and values contain at most 255 characters; keys use [a-z0-9._-]. - service_identity_id (
str, format:uuid, optional) — Optional client-provided UUID; generated by the server when omitted.
Returns:
ServiceIdentityResponse
Raises:
APIError— Any other non-2xx HTTP response (base class; exposesstatus_codeandbody).
Example
identity = client.service_identities.create(
display_name="production-indexer",
description="Indexes newly uploaded memories",
labels={"environment": "production"},
)Get a service identity
service_identities.get(*, id: str, include_deleted: bool = None) → ServiceIdentityResponse
Returns a service identity after applying READ_SERVICE_IDENTITY authority. include_deleted permits an authorized caller to inspect a permanent tombstone; it does not grant additional authority.
Parameters:
- id (
str) — Service-identity UUID - include_deleted (
bool, optional, server default=False) — Permit an authorized read of a permanent tombstone
Returns:
ServiceIdentityResponse
Raises:
APIError— Any other non-2xx HTTP response (base class; exposesstatus_codeandbody).
Example
fetched_identity = client.service_identities.get(
id=identity.service_identity_id,
)List service identities
service_identities.list(*, include_deleted: bool = None, label: dict[str, str] = None, max_results: int = None, next_token: str = None, owner_principal_id: str = None) → Page[ServiceIdentityResponse]
Requires LIST_SERVICE_IDENTITY on the GoodMem instance and READ_SERVICE_IDENTITY on each returned row. Owner and label filters, lifecycle filtering, authorization, and keyset pagination execute in PostgreSQL.
LABEL FILTERS: Label filters accept either label.<key>=<value> or label[key]=value (for example, label.environment=production or label[environment]=production).
Parameters:
- include_deleted (
bool, optional, server default=False) — Include readable permanent tombstones - label (
dict[str, str], optional) — Filter by label key-value pairs. Label filters accept either label.<key>=<value> or label[key]=value (for example, label.environment=production or label[environment]=production). - max_results (
int, format:int32, optional, server default=50) — Page size; defaults to 50 and must be between 1 and 1000 - next_token (
str, optional) — Opaque continuation token - owner_principal_id (
str, optional) — Exact current administrative-owner principal UUID
Returns:
Page[ServiceIdentityResponse]
Raises:
PermissionDeniedError— The caller lacks the permission the operation requires.APIError— Any other non-2xx HTTP response (base class; exposesstatus_codeandbody).
Example
for item in client.service_identities.list(max_results=25):
print(item.service_identity_id, item.display_name)Update a service identity
service_identities.update(*, id: str, request: UpdateServiceIdentityRequest | dict) → ServiceIdentityResponse
Updates only fields present in the request. Empty description clears that optional field. Ownership changes use the dedicated transfer endpoint.
Parameters:
- id (
str) — The unique identifier of the resource to update. - request (
UpdateServiceIdentityRequest | dict) — The update payload. Accepts a UpdateServiceIdentityRequest instance or a plain dict with the same fields. Only specified fields will be modified.
Returns:
ServiceIdentityResponse
Raises:
APIError— Any other non-2xx HTTP response (base class; exposesstatus_codeandbody).
Example
updated_identity = client.service_identities.update(
id=fetched_identity.service_identity_id,
request={"description": "Indexes production knowledge sources"},
)Delete a service identity
service_identities.delete(*, id: str) → None
Permanently soft-deletes the principal. Its stored credentials remain audit records but can no longer authenticate because their subject is deleted. Repeating an authorized delete succeeds without rewriting audit data.
Parameters:
- id (
str) — Service-identity UUID
Returns:
None
Raises:
APIError— Any other non-2xx HTTP response (base class; exposesstatus_codeandbody).
Example
client.service_identities.delete(
id=transferred.service_identity.service_identity_id,
)Transfer service-identity ownership
service_identities.transfer_ownership(*, id: str, request: TransferOwnershipRequest | dict) → TransferServiceIdentityOwnershipResponse
Transfers administrative ownership to another active principal. A service identity cannot own itself. The service identity's subject, immutable creator, credentials, grants, and roles are unchanged.
Parameters:
- id (
str) — Service-identity UUID - request (
TransferOwnershipRequest | dict) — Update payload. Pass a TransferOwnershipRequest instance or a plain dict (validated automatically).
Returns:
TransferServiceIdentityOwnershipResponse
Raises:
APIError— Any other non-2xx HTTP response (base class; exposesstatus_codeandbody).
Example
transferred = client.service_identities.transfer_ownership(
id=updated_identity.service_identity_id,
request={"new_owner_id": "70e025f6-76ca-4cbe-b8fc-7dab8e84590a"},
)Async usage: client.service_identities exposes the same methods on AsyncGoodmem; use await / async for as needed.
Data Models
All data models are pydantic v2 models. Fields are shown with their Python attribute names; JSON responses use camelCase aliases (e.g., owner_id → ownerId).
ServiceIdentityResponse
A durable production workload identity. Credentials, grants, and roles are separate resources and are not included.
- service_identity_id (
str) — OUTPUT_ONLY; immutable service-identity UUID. - display_name (
str) — OUTPUT_ONLY; unique operator-facing display name. - description (
str, optional) — OUTPUT_ONLY; optional operator description. - owner_principal_id (
str) — OUTPUT_ONLY; current administrative owner principal UUID. - creator_principal_id (
str) — OUTPUT_ONLY; immutable HUMAN creator-principal UUID. - labels (
dict[str, str]) — OUTPUT_ONLY; mutable labels. At most 20 entries; keys and values contain at most 255 characters; keys use [a-z0-9._-]. - deleted_at (
int, optional) — OUTPUT_ONLY; permanent deletion time in milliseconds, absent while active. - deleted_by_id (
str, optional) — OUTPUT_ONLY; exact deleting actor UUID, absent while active. - created_at (
int) — OUTPUT_ONLY; creation time in milliseconds since the epoch. - updated_at (
int) — OUTPUT_ONLY; most recent mutation time in milliseconds since the epoch. - created_by_id (
str) — OUTPUT_ONLY; exact creating actor UUID. - updated_by_id (
str) — OUTPUT_ONLY; exact actor UUID for the most recent mutation.
UpdateServiceIdentityRequest
Updates explicitly present profile fields. Empty description clears it; omitted fields remain unchanged. Ownership is changed only through the transfer endpoint.
- display_name (
str, optional) — Replacement display name. A present blank value is invalid. - description (
str, optional) — Replacement description. An empty string clears the description. - replace_labels (
dict[str, str], optional) — Complete replacement label map; an empty map clears all labels and is mutually exclusive with merge_labels. At most 20 entries; keys and values contain at most 255 characters; keys use [a-z0-9._-]. - merge_labels (
dict[str, str], optional) — Labels to upsert; must contain at least one entry and is mutually exclusive with replace_labels. The final stored map may contain at most 20 entries; keys and values contain at most 255 characters; keys use [a-z0-9._-].
TransferServiceIdentityOwnershipResponse
The service identity after its administrative ownership transfer.
- service_identity (
ServiceIdentityResponse) — OUTPUT_ONLY; updated service identity.