Add consumer organization selection to a website

Use the verified Token/PHP 0.1.4 package behind the website to call M7IdentitySDK::managedOrganizations(token, options). It includes the Organizations and Emails classes. Follow the package installation and root layout alongside the website installation.

The requesting app must also be allowed by each org owner's discovery policy. Only stored owners edit Access → Policy. Ordered app/org ACL rules use the first match; a deny cannot be bypassed by membership role. With no match, an app owned by that org uses same_org_discoverable, and other apps use discoverable; both default off. App identity and ownership come from the validated token's client_id. App ownership, the caller's Management membership, owner permission to disclose, and website resource authorization are separate checks. An empty success can reflect policy filtering; a failed lookup is an error. Local imported identities cannot bypass this policy. See the full disclosure contract.

  1. Register orgs for the consumer OAuth client, explicitly request it in hosted authorization and obtain consent. Keep PKCE/state/nonce and the registered client/sender-binding policy. Device authorization rejects orgs.
  2. Use the active login token and verified consumer subject/client ID. The org helper does not own a browser session, acquire/refresh a bundle, generate proofs or persist org results. An orgs-only token can call the org endpoint; standard UserInfo still requires openid.
  3. Resolve the trusted endpoint before producing a fresh DPoP proof, then fix that endpoint in the request. A proof for UserInfo or the website API cannot authorize this different resource. For mTLS use the discovered top-level m7_mtls_orgs_endpoint and bound certificate.
  4. Accept only a successful report and exact subject binding. Render org names, scopes, tag data and public JSON as literal text. Empty org lists are valid; failed reports are errors and carry no accepted orgs/subject. Preserve nonce challenges for explicit fresh-proof recovery.
  5. Apply your website's resource policy to the live facts. Seeing an org or a role/tag is not a grant to its buckets/blogs. Original identity-only results remain compatible but grant no absent authorization facts.
use M7\Identity\M7IdentitySDK;

$sdk = new M7IdentitySDK();
$options = ['client_id' => $verifiedClientId, 'expected_sub' => $verifiedSubject];
$endpoint = $sdk->managedOrganizationsEndpoint($options);
$options['endpoint'] = $endpoint;
// For a bound token, add a caller-created POST proof for $endpoint and $token.
$report = $sdk->managedOrganizations($token, $options);
if (!$report->ok()) {
    throw new RuntimeException($report->reason() ?? 'Organization lookup failed');
}

Current results carry caller access_level and one implicit Management group/membership, role, membership pub, and assigned tags with definition data, plus per-org consumer and tenant app lists (id, client_id, name). The lists contain the org's live owned registrations and show related apps; they do not grant access between apps. These are three distinct data locations when compared with org organization.data. Only public membership data is exported; no pri, other principals or expiry fields. PHP associative decoding makes empty objects []. $report->client() separately identifies the token's app. A personal consumer app has org: null and tenant {id: "00000000-0000-0000-0000-000000000000", slug: "m7-identity-consumer"}; a policy-hidden org-owned app has client: null. See the complete validation/report/options contract and SSO normative org profile. Registered signed/encrypted response policy must pass verification before facts are trusted. Optional certificate/validation caches remain separate from org result persistence, which this operation does not supply.

Backend workers can also use an ordinary client-credentials token with explicitly requested registered orgs. Bind expected_sub to the verified public client_id and assign that app its own Management membership; creator access and registration ownership do not substitute for membership. Personal owner proxies and tenant member tokens cannot use this endpoint.

API BigFS already uses the platform remote service to transport these facts; its local import boundary stores org identity only. See BigFS acquisition and upgrade order. Consumer-service permission adoption is separate; Blog adoption remains future work. For the distinct API User email list use account emails.