Inforcer Tenant Management — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Inforcer Tenant Management (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Tenants are the top-level scope in Inforcer. Alignment, secure score, identity inventory, audit, and assessment calls are all scoped to a single managed tenant. Knowing how to enumerate tenants and resolve a friendly name to its integer Client Tenant ID is the first step in almost every Inforcer workflow.
Read api-patterns first for the gateway headers, the region requirement, the envelope, and pagination.
inforcer_tenants_listList every Microsoft 365 tenant Inforcer manages. Returns tenant objects including the integer Client Tenant ID, display name, the default/primary domain, and (where present) the Azure AD tenant GUID.
inforcer_tenants_list()Use this whenever a user refers to a client by name — the response is how you resolve that name to the integer Client Tenant ID needed by every tenant-scoped tool. Page through continuationToken until it is absent so the list is complete.
Inforcer's tenant-scoped paths take an integer Client Tenant ID — not the Azure AD GUID and not the domain.
| Identifier | Use directly in a tenant path? |
|---|---|
Integer Client Tenant ID (e.g. 1423) | Yes |
Azure AD tenant GUID (00000000-…) | No — resolve first |
Tenant domain (contoso.onmicrosoft.com) | No — resolve first |
Friendly display name (Contoso) | No — resolve first |
The MCP server resolves friendly names, DNS domains, and Azure AD GUIDs to the integer Client Tenant ID for you. You can therefore say "scope to Contoso" — but under the hood the path is the integer id. When a tenant-scoped call returns nothing, the usual cause is a GUID or domain that never got mapped to the integer id. Re-run inforcer_tenants_list and confirm the resolution. Never guess the tenant identifier.
Every Inforcer call depends on INFORCER_REGION (us, uk, eu, or anz) because the upstream host is region-specific. If inforcer_tenants_list returns empty or 401/403, confirm the region matches the region your API key belongs to before assuming the tenant list is genuinely empty.
Resolve a friendly name → Client Tenant ID
tenants = inforcer_tenants_list()
acme = next(t for t in tenants if 'acme' in t['displayName'].lower())
client_tenant_id = acme['clientTenantId'] # integerPass client_tenant_id to alignment, secure score, identity, audit, and assessment tools.
Build a portfolio loop
List once, then iterate every tenant's integer Client Tenant ID for fleet-wide reports (drift roll-ups, posture scorecards). Always page continuationToken to completion first — a partial tenant list silently drops clients from the report.
INFORCER_REGIONpoints at the wrong host) or a key with no tenant scope. Confirm region and key scope before concluding there are no managed tenants.
domain reached the path instead of the integer Client Tenant ID. Re-resolve via inforcer_tenants_list.
id; the GUID and domain are only inputs to resolution.
field names like clientTenantId are illustrative and credited to royklo/InforcerCommunity. Verify the exact field on first use.
management here is read-only enumeration and resolution.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.