GDAP auto-renewal

GDAP relationships are time-boxed — Microsoft caps the duration at 730 days. When a relationship hits its end date it stops working, Manage365 can't call Graph for that tenant, and whatever scans, pushes, or alerts you had running quietly break. This page explains the 730-day cliff problem and how Manage365 prevents it.

The 730-day cliff

Microsoft's GDAP model defines one contract per (partner, customer) pair. Each contract:

  • Is created with a duration between 1 and 730 days
  • Cannot be extended — you create a replacement before it expires or you lose access on expiry
  • Does not reissue itself; every replacement is a separate Microsoft customer-admin acceptance

In practice: if you invited 60 customer tenants two years ago, they'll all expire within a narrow window, and every one needs a fresh invite accepted by the customer's Global Admin. Miss the window and your scans silently go quiet on that tenant.

How Manage365 handles it

Once an hour a scheduler sweeps every GDAP relationship Manage365 is aware of and buckets them by time-to-expiry:

  • Warning window — relationships expiring in less than 90 days. Auto-replacement candidates.
  • Critical window — relationships expiring in less than 30 days. Auto-replacement + escalated alert.
  • Expired — already dead. No auto-replacement possible (gap can't be closed automatically); critical alert raised.

Auto-replacement flow

For every relationship in the warning or critical window, Manage365:

  1. Fetches the current relationship's role set from Microsoft Partner Center
  2. Creates a replacement invite that mirrors the existing roles and the original duration (usually 730 days)
  3. Stores the replacement's invite URL on the tenant record
  4. Raises a dedup-keyed alert for the tech — category gdap, severity scaling with the window (warning = medium, critical = high)

The alert carries the invite URL and a one-line summary of the roles in the replacement. You forward it to the customer, they Global-Admin accept, and the new relationship goes active overlapping with the old one — no outage.

Dedupe

Each alert's dedupe key is gdap.renewal.<tenantId>.<expiryMonth>. The hourly sweep re-fires the same key, which just bumps the alert count and last-seen time — you don't get 24 alerts a day for the same expiring relationship.

Expired relationships

If an hourly sweep finds a relationship that has already expired (gap exists — you missed the window or the customer didn't accept in time):

  • A critical alert is raised with dedupe key gdap.expired.<tenantId>
  • No auto-replacement is attempted — a gap already exists, so the tenant needs a fresh invite accepted before anything works again
  • Compliance scans, standards pushes, and MSP library operations skip the tenant with a logged reason until the new relationship is active

Expiry is an awkward state, but the alert is unambiguous: the tenant is out of contact and a human needs to send a new invite.

Role-set mirroring

The replacement invite uses the same set of roles the expiring relationship had, not the default 10-role set from GDAP setup. This matters because many MSPs trim the default set for specific tenants (a read-only review engagement, for example). Renewal preserves that trimmed set — it doesn't silently grant more.

If you've added roles to your default after the original invite, those new roles aren't backfilled automatically. Add them via the GDAP tab on the tenant after the replacement is accepted.

Scheduler visibility

The system-health page shows the last run time of the auto-renewal sweep, plus a count of relationships it found in each bucket. If it hasn't run in over two hours, something is wrong with the BullMQ worker or Partner Center API — check the alerts stream for a scheduler health alert.

End-to-end example

  1. You invited Acme Health on 15/04/2024 with the 10-role default + 730-day duration. Expiry: 15/04/2026.
  2. On 15/01/2026 (90 days out) the hourly sweep fires; an alert appears: GDAP renewal required — Acme Health (expires 15/04/2026) with an invite URL.
  3. You forward the URL to the customer's Global Admin. They accept on 22/01/2026.
  4. From 22/01/2026 onwards there are two overlapping relationships. The alert auto-resolves when Manage365 detects a new relationship with overlapping validity.
  5. On 15/04/2026 the old relationship expires. Manage365 already has the new one — no gap.

Common pitfalls

  • Customer sat on the invite — the replacement was auto-generated but the customer's Global Admin didn't accept. The relationship still expires on its original date. Escalate when the critical window hits (30 days out) if the replacement is still unaccepted.
  • Global Admin left the tenant — a common scenario. The original invite was accepted by a person who no longer exists. A new Global Admin needs to accept the replacement.
  • Partner Center outage — the sweep can't create the replacement if Partner Center is down. A scheduler-health alert fires. The sweep retries hourly until it succeeds.
  • Roles changed in Partner Center manually — the sweep mirrors what it sees at sweep time. If you've tweaked roles in the Partner Center UI in the last hour, the mirror may lag briefly.

FAQ

Can I disable auto-renewal per tenant? Not yet. The workaround is to revoke the GDAP relationship manually — the sweep can't create a replacement for a revoked one.

Does the sweep cost anything? It's just Partner Center API calls + DB writes. No Microsoft billing impact; no Manage365 invoice impact.

What if the customer tenant is being offboarded? Suspend or delete the tenant in Manage365 before the warning window hits. Suspended + deleted tenants are skipped by the sweep.