External service prerequisites
Prepare these services before automatic entitlement refresh, EcasRoot checks, or mailbox reset. Put real configuration values in server secret storage. See Microsoft Graph setup for application registration and authorization for app permissions.
The administrator interface does not request, display, or store S3/OpenSearch credentials. Database-managed provider secrets in that interface apply to AI providers.
Microsoft Entra and Graph
The tenant connection's application needs these Graph Application permissions with tenant administrator consent:
| Permission | Purpose |
|---|---|
RoleManagement.Read.Directory | Read active Global Administrator assignments for EcasRoot |
LicenseAssignment.Read.All | Read tenant subscribedSkus |
User.Read.All | Read users, assignedLicenses, and supported membership data |
In the application's API permissions, add the missing application permissions and grant consent for this tenant. Keep existing mailbox permissions. Do not add directory-write permissions for this read-only entitlement workflow.
The Global Administrator assignment must be active. A PIM-eligible but inactive role does not grant EcasRoot. The supported role assignment has tenant-wide / scope, directly or through a group. After consent changes, use the supported scoped runtime procedure to get fresh provider tokens.
Mailbox reset does not delete Microsoft mail or accounts. It needs no wider mailbox provider permission. Exchange restrictions must still allow access to mailboxes that need another onboarding run.
S3-compatible storage
The backend identity needs these operations within the application bucket:
| Operation | AWS IAM equivalent or condition |
|---|---|
ListObjectsV2 | s3:ListBucket |
DeleteObject | s3:DeleteObject |
ListObjectVersions | s3:ListBucketVersions when versioning is enabled |
| Delete a version | s3:DeleteObjectVersion when versioning is enabled |
GetObject, PutObject | Required by existing import and body-storage paths |
Restrict access to the application's users/* and legacy email-bodies/* scopes. Configure:
S3_ENDPOINT
S3_REGION
S3_ACCESS_KEY
S3_SECRET_KEY
S3_BUCKET_EMAIL_BODIES
S3_FORCE_PATH_STYLE
Keep credentials in server configuration, outside browser/admin responses. Reset must remove all versions and delete markers in a versioned bucket. A simple delete marker is not full deletion.
Object Lock compliance retention or legal hold can prevent reset. The default reset reports a blocked state rather than bypassing retention. Governance bypass requires separate authority and a workflow that supports it. Local development SeaweedFS uses a non-versioned bucket prepared by its setup path.
OpenSearch
Restrict the service role to MailGen mail indexes:
{OPENSEARCH_INDEX}
{OPENSEARCH_INDEX}-v2
{OPENSEARCH_INDEX}-v3
{OPENSEARCH_INDEX}-readiness
Reset needs search/count, indices:data/write/delete/byquery, indices:admin/refresh, and read access for index existence/resolution. It deletes mailbox documents, not the whole index. It needs no cluster-admin or index-delete permission.
An active REST allowlist must permit POST /{index}/_delete_by_query, GET or POST /{index}/_count, POST /{index}/_refresh, and index-existence checks.
Configure the server's endpoint, index, and credentials:
OPENSEARCH_URL
OPENSEARCH_INDEX
OPENSEARCH_USERNAME
OPENSEARCH_PASSWORD
HTTP entitlement source
This section applies only to HTTP-based automatic membership.
- Add the hostname to comma-separated
ECAS_ENTITLEMENT_ALLOWED_HOSTS. - Use a public IPv4 HTTPS destination on port 443.
- Return HTTP 200 within ten seconds, with at most 1024 bytes.
- Return
1,0,true,false,"true", or"false". - Handle repeated checks idempotently.
Redirects, URL credentials, private addresses, and file input are unsupported. The server substitutes the Microsoft Graph user ID for USER_ID. cURL import parses configuration without a network call. Actual execution still enforces destination and allowlist constraints.
Preflight checks
The backend command below makes real disposable S3 and OpenSearch writes. Prepare the scoped credentials first. Run it from the configured backend environment:
pnpm authorization:external-preflight
The check inspects Graph application-role claims, Global Administrator readability, tenant licenses, and user assignedLicenses. It creates, lists, and removes an object under users/__ecas_preflight__/probes/. With supported versioning, it also removes probe versions and markers. OpenSearch cleanup targets a random ecasPreflightId through delete-by-query.
Success requires ready states, probe cleanup, and a successful exit. On failure, inspect only the identified remaining probe. Do not delete a broad prefix or index. Share states, safe error codes, and missing permission names, never credentials or tokens.