Acquire organization memberships and apps through API BigFS
The current integration transports caller-bound M7 organization facts:
BigFS -> API BigFS -> platform remote organizations -> Identity SDK -> SSO
Use a consumer user or ordinary client-credentials application token with an
accepted API BigFS audience and the existing token/sender-binding/principal
checks. The organization routes permit apps backing either a consumer or tenant
directory; tenant member tokens and personal machine-owner proxies are rejected.
They require the canonical issuer https://sso.user.m7.org and verified token
sub/client_id; the broader legacy issuer policy does not override this check.
For apps, sub must match the public client_id, and SSO returns the app's own
explicit Management memberships. Creator access is never inherited.
Register and explicitly request orgs; consumer sign-in requires hosted consent.
The scope and app inventory do not grant bucket or vault permissions. Device
authorization currently rejects orgs. Other resource routes retain their
existing token-mode and resource-access rules.
Owner-controlled visibility
SSO applies each org owner's discovery policy to the requesting OAuth app before
returning membership public data, tags or app inventories. Requester registration
and owning org are resolved from the validated token's client_id; request body
org/tenant values cannot select the policy identity. The requester can be a
personal or org-owned app.
Only stored owners read/write discovery policy. Ordered app/org rules use the
first match across both types. With no match, apps owned by the disclosed org use
same_org_discoverable; all other apps use discoverable. Both default off.
An explicit deny remains authoritative even for owner/admin/member callers.
Owners opt in BigFS's public Client ID or owning org through User M7 Access →
Policy; the saved app rule binds a registration UUID, so a recreated Client ID
does not inherit the old allow. See policy controls.
An allow grants disclosure of existing membership facts. Registration ownership does not grant membership, and membership/disclosure does not grant bucket or vault access. A successful empty list may reflect policy filtering. Failed policy/storage lookup is an error, not an empty success. Local imported references cannot bypass a fresh lookup under current discovery policy.
Resolve and search
Send POST JSON to both routes:
Path under https://api.bigfs.m7.org |
Input | Success |
|---|---|---|
/v1/organization/endpoint |
{} |
status: 1, data.endpoint: trusted discovered SSO org URL. |
/v1/organization/search |
{} for unbound tokens; orgs_dpop for a bound token |
status: 1, data.sub, data.orgs: SDK-validated caller projection. |
curl --fail-with-body --silent --show-error \
'https://api.bigfs.m7.org/v1/organization/search' \
--header 'Authorization: Bearer ACCESS_TOKEN' \
--header 'Content-Type: application/json' --data '{}'
For a DPoP-bound token obtain the endpoint first. API BigFS's normal DPoP
header binds the API request. The separate JSON orgs_dpop proof binds the
discovered SSO org endpoint, POST and the same token/ath, with original
key and fresh jti. It must be a string at most 8,192 bytes, without CR/LF or
comma coalescing. The server forwards it to SSO; it never fabricates a proof.
Each API call still requires its own normal API proof when bound.
Successful rows preserve org ID/name/slug, caller access_level and
management_groups: group/membership ID/name/role, membership pub, and tags
with ID/name/slug/definition data. Each org also contains consumer and
tenant lists of its owned active, unarchived, unexpired registrations, split
by nil/non-nil tenant directory. App descriptors contain only id, client_id
and name, with no app slug. The public client_id need not be a UUID;
they show shared ownership and convey no permission to call those
apps. Both lists can be empty. Older responses omitting both retain their
absence; malformed or partial inventories fail the request.
The provider currently has one implicit
Management group per org. See the
SSO projection and
SDK validation.
Other principals, private pri, internal metadata and expiry fields are excluded.
Empty lists are valid; original identity-only rows confer no absent access facts.
Failures and freshness
Endpoint discovery failure is a 502 route failure with safe prose. Missing
required orgs_dpop returns status: 0, error: "invalid_dpop_proof".
Upstream scope/transport/validation failures return status: 0, an OAuth error
or orgs_upstream_failed, safe comment, and data.dpop_nonce when available.
Do not infer success from HTTP status alone or turn failure into an empty list.
Current SSO does not issue nonces; the adapter preserves an upstream challenge
and BigFS can explicitly retry once with a fresh nonce-bearing SSO proof.
The caller's sub and client_id come from verified claims, not body selectors.
Each search uses a fresh SSO membership lookup and signed/encrypted response
verification when registered. Permission changes and departure affect the next
lookup; a saved selection is not continuing authority. The normal
API BigFS authorization guide still governs resources.
Platform service and local import boundary
Reusable PHP service:
platform\service\remote\organizations\Organization.
endpoint(context) resolves the trusted URI; available(token, context) returns
the full live ManagedOrganizationsReport without SQL. Context permits only
verified client_id, expected_sub, and caller dpop; constructor options own
trusted issuer/endpoint/certificate/transport policy. Unknown options fail.
The service does not refresh/retry, create proofs or store credentials.
Optional backend import(remoteID, token, context) and
refresh(localID, token, context) each reacquire live visibility and pass only
remote org ID/name/slug to the application-local import repository. Local
issuer/reference/status/timestamps support tracking, not authorization. Caller
role/scopes/tag data/membership pub and consumer/tenant app inventories are
never stored as durable import authority.
Remote failures/lost visibility leave existing references unchanged. Applications
authorize import and resource associations themselves; these routes expose live
lookup, not a new HTTP import API.
Installation and frontend pickup
Install API User management tags and configured membership metadata before SSO
reads them, then SSO endpoint/scope/discovery, complete updated SDK source,
shared platform/bootstrap, API BigFS and the BigFS client. See
upgrade order
and PHP root configuration.
M7_LIB_ROOT needs namespace.php; M7_PLATFORM_ROOT needs require/startup;
platform M7_IDENTITY_TOKEN_ROOT needs packages/token-php/autoload.php.
Live lookup needs no local import table; optional import storage needs normal
SQL quote/UUID helpers and its repository installer. Existing schemas are not
blanket replaced. Later role/modal/departure slices add no extra schema.
BigFS app sign-in adds orgs for the canonical consumer issuer; the client
must register it and a new token must obtain consent. Tenant issuer sign-in is
not converted into consumer org access. The Organizations integration page at
/members/orgs/ uses the configured API client, endpoint then search, separate
SSO proof and bounded nonce recovery. It displays access/membership IDs and roles,
scopes, expandable tag data and membership public JSON, plus separate consumer
and tenant app sections with names, app IDs and client IDs as literal text. Empty,
legacy and missing facts remain explicit. Changed sessions discard a pending
result; scope failure offers sign-in again and other failures remain retryable.
Current source and synthetic checks verify transport/display/import boundaries. Live deployment acceptance of this response is not established here; the current SDK org/email operations are unreleased. Seeing these facts does not authorize bucket or blog operations. Consumers define scope semantics and resource policy; Blog adoption remains future work. Admin delegation and read-only app/key inventory are deferred; the standalone catalogue UI was cancelled and membership expiry was not added.