> ## Documentation Index
> Fetch the complete documentation index at: https://docs.transluce.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Organization administration

> Manage organizations, audit events, Microsoft Entra mappings, and service accounts

Organization administrators can perform the same governance and identity tasks
through the Python SDK that are available under **Settings → Organizations**.
The calling user or service account must be an administrator of the target
organization.

## Create and update an organization

```python theme={null}
from docent import Docent

client = Docent(api_key="your-organization-admin-key")

organization = client.create_organization(
    "Production evaluation",
    description="Production agent evaluation data",
)
organization_id = organization["id"]

client.update_organization(
    organization_id,
    name="Production evaluation",
    description="Production and pre-release evaluation data",
)
```

## Manage members

```python theme={null}
members = client.add_organization_member(
    organization_id,
    "operator@example.com",
    role="member",
)

operator = next(member for member in members if member["user"]["email"] == "operator@example.com")
client.update_organization_member_role(organization_id, operator["user"]["id"], "admin")
client.remove_organization_member(organization_id, operator["user"]["id"])
```

Direct membership and Microsoft Entra group membership are independent access
sources. Removing a direct grant does not remove access supplied by a mapped
Entra group. Pass `create_manual_grant=True` only when you intentionally want a
direct grant to remain after the person leaves that group.

## Read and download audit events

List recent events with cursor pagination:

```python theme={null}
from datetime import datetime

events = client.get_organization_audit_events(organization_id, limit=100)

last_event = events[-1]
older_events = client.get_organization_audit_events(
    organization_id,
    limit=100,
    before=datetime.fromisoformat(last_event["created_at"]),
    before_id=last_event["id"],
)
```

`before` must be a timezone-aware `datetime`. To download every event in a
half-open time range—`start_at` is included and `end_at` is excluded—use:

```python theme={null}
from datetime import UTC, datetime

path = client.download_organization_audit_events(
    organization_id,
    start_at=datetime(2026, 8, 1, tzinfo=UTC),
    end_at=datetime(2026, 9, 1, tzinfo=UTC),
    output_path="august-organization-audit.csv",
)
```

The download is streamed to a temporary file and atomically moved to
`output_path` after it succeeds.

## Map a Microsoft Entra group

In an Entra-enabled deployment, Docent searches Microsoft Graph using
the read-only `GroupMember.Read.All` and `User.ReadBasic.All` application
permissions approved by the tenant administrator. Mapping by name is
convenient, while Docent stores the immutable group object ID:

```python theme={null}
mapping = client.set_entra_group_mapping_by_name(
    organization_id,
    "Production operators",
)
print(mapping["group_id"], mapping["group_display_name"])
```

If no security group has that exact display name, or multiple groups share it,
the method raises `ValueError` without changing the mapping. Call
`search_entra_groups` and then `set_entra_group_mapping` when you need to select
an object ID explicitly.

To replace a deleted or renamed group, call either setter again. Replacing the
object ID immediately removes access derived from the old mapping and records
the transition in the audit log. Members of the replacement group receive
access on their next Microsoft sign-in. Direct Docent grants remain intact.

```python theme={null}
client.set_entra_group_mapping(organization_id, "new-group-object-id")
client.clear_entra_group_mapping(organization_id)
```

When the tenant has organization group mappings, Docent retrieves the user's
complete transitive security-group IDs from Graph during Microsoft sign-in. If
Graph cannot provide the complete list, the sign-in is rejected and existing
group access is not incorrectly retained. Tenants without group mappings do not
depend on this Graph lookup for sign-in.

## Create a service account

```python theme={null}
service_account = client.create_service_account(
    organization_id,
    "Production ingestion",
    permission="write",
    description="Uploads production agent runs",
)
service_account_id = service_account["id"]
```

### API key

```python theme={null}
credential = client.create_service_account_api_key(
    organization_id,
    service_account_id,
    "Production secret",
)
print(credential["secret"])  # Store once; it is not returned again.
```

### Microsoft Entra workload

```python theme={null}
client.set_service_account_entra_identity(
    organization_id,
    service_account_id,
    client_id="application-client-id",
    service_principal_id="enterprise-application-object-id",
)
```

The enterprise application must have the deployment's service-account app role.

### AWS outbound OIDC workload

```python theme={null}
client.set_service_account_aws_identity(
    organization_id,
    service_account_id,
    role_arn="arn:aws:iam::123456789012:role/production/DocentIngestion",
    oidc_issuer_url="https://issuer-id.tokens.sts.global.api.aws",
)
```

The issuer is account-specific and is required for new AWS outbound OIDC
bindings. Omitting it creates a legacy signed-request binding. See
[Authentication](/sdk/authentication#aws-outbound-oidc) for workload setup.

Disabling a service account revokes all of its API keys, Entra identity, and AWS
identity for subsequent requests:

```python theme={null}
client.disable_service_account(organization_id, service_account_id)
```
