---
id: CAP-PFM-TNL-004
title: Prepare the customer’s first access and sender
feature: FEAT-PFM-TNL-01
product_area: platform
module: tenant-lifecycle
revision: 2
status: draft
product_intent: proposed
implementation_evidence: observed
supersedes: []
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
intent_sources:
  - 'services-platform:docs/tenants/tenant-lifecycle-plan.md#§4.3'
  - 'services-platform:docs/hq/rhythm-hq-plan.md#§K decision record K3, K5'
purpose: >-
  Provisioning establishes the requested first administrator and sender without
  waiting for customer DNS work.
outcomes:
  - >-
    A named first administrator for a new customer receives one customer-level
    invitation.
  - Sender setup proceeds while DNS verification remains pending.
  - Portal interest is retained for later onboarding.
concepts:
  - CON-PFM-TNL-002
actors:
  - ACT-PFM-004
  - ACT-PFM-012
surfaces:
  - console
  - api
  - job
preconditions: []
postconditions: []
permissions:
  - key: hq.tenants.provision
    where_checked: api
    scope: global
rules:
  - id: BR-CAP-PFM-TNL-004-01
    proved_by: [ATS-PFM-TNL-004-01, TST-PFM-TNL-082]
    statement: >-
      Provisioning invites a named first administrator only when the request
      also creates the customer.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#invites
      nobody when the request did not create the customer
    origin: >-
      services-platform:docs/tenants/tenant-lifecycle-plan.md#§4.3
      platform.security (approved 2026-10-09)
  - id: BR-CAP-PFM-TNL-004-02
    proved_by: [ATS-PFM-TNL-004-02]
    statement: >-
      The invitation gives a console user the built-in Administrator role at
      customer scope, pending acceptance.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/lifecycle/first-administrator.integration.spec.js#grants
      that user the Administrator role at the customer, waiting on their
      acceptance
    origin: >-
      services-platform:docs/tenants/tenant-lifecycle-plan.md#§4.3 (approved
      2026-10-09)
  - id: BR-CAP-PFM-TNL-004-03
    proved_by: [ATS-PFM-TNL-004-03]
    statement: >-
      Retry adopts a compatible existing administrator or invitation instead of
      sending a second invitation.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#does
      not invite them a second time when the provisioning is run again
    origin: >-
      services-platform:docs/tenants/tenant-lifecycle-plan.md#§4.3 seed key
      first-administrator-invitation (approved 2026-10-09)
  - id: BR-CAP-PFM-TNL-004-04
    proved_by: [ATS-PFM-TNL-004-04, ATS-PFM-TNL-004-10]
    statement: >-
      An existing person without usable customer administration authority causes
      refusal, including suspension, the wrong role or scope, or an ineffective
      grant period.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/unit/services/lifecycle/first-administrator.spec.ts#refuses
      a SUSPENDED user, whatever they hold: an administrator nobody can use is
      none
    origin: none
  - id: BR-CAP-PFM-TNL-004-05
    proved_by: [ATS-PFM-TNL-004-05, TST-PFM-TNL-085]
    statement: >-
      Sender validation rejects unsupported strategies, invalid domain
      hostnames, domains on address-only strategies and addresses outside the
      chosen domain before request writes.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/provisioning/tenant-email-strategy.integration.spec.js#refuses
      an address outside the domain, because an identity proved for one domain
      may not send as another
    origin: >-
      services-platform:docs/hq/rhythm-hq-plan.md#§D5 option A (K3, Andrew
      2026-10-11)
  - id: BR-CAP-PFM-TNL-004-06
    proved_by: [ATS-PFM-TNL-004-06]
    statement: >-
      A domain sender request can use the workspace’s hostname identifier when
      no domain is supplied.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/provisioning/tenant-email-strategy.integration.spec.js#proves
      the tenant’s id as the domain, the id being a hostname
    origin: 'services-platform:docs/hq/rhythm-hq-plan.md#§D5 (K3)'
  - id: BR-CAP-PFM-TNL-004-07
    proved_by: [ATS-PFM-TNL-004-07]
    statement: >-
      Provisioning creates sender identities and opens without DNS verification;
      pending identities leave mail using Rhythm’s shared sender.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/provisioning/tenant-email-strategy.integration.spec.js#opens
      the tenant anyway, which is what option A promises
    origin: >-
      services-platform:docs/hq/rhythm-hq-plan.md#§D5 option A (K3, Andrew
      2026-10-11)
  - id: BR-CAP-PFM-TNL-004-08
    proved_by: []
    statement: >-
      Without a sender strategy, provisioning creates no sender identity and
      retains shared sending.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/provisioning/tenant-email-strategy.integration.spec.js#writes
      no sender identity, because the shared Rhythm sender is the answer for
      most tenants
    origin: 'services-platform:docs/hq/rhythm-hq-plan.md#§D5 (K3)'
  - id: BR-CAP-PFM-TNL-004-09
    proved_by: [ATS-PFM-TNL-004-08, TST-PFM-TNL-097]
    statement: >-
      Provisioning records a portal request without building a portal sign-in
      pool.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/unit/services/lifecycle/participants.spec.js#creates
      nothing when a tenant is provisioned, because the pool is built when
      Websites is enabled
    origin: >-
      services-platform:docs/tenants/tenant-lifecycle-plan.md#§4.3
      security.portal-pool (Andrew, 2026-10-16);
      services-platform:docs/hq/rhythm-hq-plan.md#§D6 (K5)
scenarios:
  - id: SC-CAP-PFM-TNL-004-01
    given: >-
      A new association names its first administrator and requests a domain
      sender.
    when: Provisioning completes.
    then: >-
      The person has one invitation, the workspace opens and sender setup
      supplies the DNS records still needed.
    provenance: test
    source: >-
      services-platform:modules/tenants/tests/integration/services/provisioning/tenant-email-strategy.integration.spec.js#opens
      the tenant anyway, which is what option A promises
edge_cases: []
constraints: []
depends_on:
  - CAP-PFM-TNL-002
related:
  - CAP-PFM-TNL-001
journeys:
  - JNY-PFM-TNL-001
open_questions: []
evidence:
  - >-
    Inspected source:
    services-platform:docs/tenants/tenant-lifecycle-plan.md#§4.3
  - >-
    Inspected source: services-platform:docs/hq/rhythm-hq-plan.md#§K decision
    record K3, K5
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#invites
    nobody when the request did not create the customer
  - >-
    Inspected source:
    services-platform:docs/tenants/tenant-lifecycle-plan.md#§4.3
    platform.security (approved 2026-10-09)
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/lifecycle/first-administrator.integration.spec.js#grants
    that user the Administrator role at the customer, waiting on their
    acceptance
  - >-
    Inspected source:
    services-platform:docs/tenants/tenant-lifecycle-plan.md#§4.3 (approved
    2026-10-09)
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/provisioning/provision-tenant.integration.spec.js#does
    not invite them a second time when the provisioning is run again
  - >-
    Inspected source:
    services-platform:docs/tenants/tenant-lifecycle-plan.md#§4.3 seed key
    first-administrator-invitation (approved 2026-10-09)
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/unit/services/lifecycle/first-administrator.spec.ts#refuses
    a SUSPENDED user, whatever they hold: an administrator nobody can use is
    none
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/provisioning/tenant-email-strategy.integration.spec.js#refuses
    an address outside the domain, because an identity proved for one domain may
    not send as another
  - >-
    Inspected source: services-platform:docs/hq/rhythm-hq-plan.md#§D5 option A
    (K3, Andrew 2026-10-11)
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/provisioning/tenant-email-strategy.integration.spec.js#proves
    the tenant’s id as the domain, the id being a hostname
  - 'Inspected source: services-platform:docs/hq/rhythm-hq-plan.md#§D5 (K3)'
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/provisioning/tenant-email-strategy.integration.spec.js#opens
    the tenant anyway, which is what option A promises
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/integration/services/provisioning/tenant-email-strategy.integration.spec.js#writes
    no sender identity, because the shared Rhythm sender is the answer for most
    tenants
  - >-
    Inspected source:
    services-platform:modules/tenants/tests/unit/services/lifecycle/participants.spec.js#creates
    nothing when a tenant is provisioned, because the pool is built when
    Websites is enabled
  - >-
    Inspected source:
    services-platform:docs/tenants/tenant-lifecycle-plan.md#§4.3
    security.portal-pool (Andrew, 2026-10-16);
    services-platform:docs/hq/rhythm-hq-plan.md#§D6 (K5)
controls: [TC-AVL-004, TC-AVL-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-005, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-IAM-001, TC-IAM-002, TC-IAM-003, TC-IAM-004, TC-IAM-005, TC-LOG-001, TC-LOG-004, TC-LOG-005, TC-MON-001, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-VEN-001, TC-VEN-002, TC-VEN-003]
exercised_by: [FAS-PFM-TNL-01-01, FAS-PFM-TNL-01-03, FAS-PFM-TNL-01-05]
suites: [TST-PFM-TNL-082, TST-PFM-TNL-085, TST-PFM-TNL-097]
---

# Prepare the customer’s first access and sender

## Purpose

Provisioning establishes the requested first administrator and sender without waiting for customer DNS work.

## How It Works

Staff can name the first administrator when creating a new customer. Provisioning gives that person the customer-scoped Administrator invitation. A compatible existing invitation or administrator is adopted on retry. An existing suspended person or ineffective grant stops the step with an explanation. Sender choices are validated before the workspace request writes anything. Domain-based choices can use the workspace’s hostname identifier when no domain is supplied. The build creates the sender identities and exposes the DNS work still required. Customer access opens without waiting for that work, with shared sending available while verification is pending. A portal request is recorded here; the portal sign-in pool belongs to later onboarding.

## Relationships

- Open a workspace after its applications are ready: The original request carries administrator and sender choices.
- Request a complete customer workspace: The capabilities share the workspace’s recorded lifecycle decision.
