# M7 Identity SDK

<!-- m7-identity-discovery:begin -->
## Connect to M7 Identity

Issuer: <https://sso.user.m7.org>

Discovery JSON: <https://sso.user.m7.org/.well-known/openid-configuration>

- [Discovery and signing keys](https://m7.org/docs/api/sso.user.m7.org/discovery-and-keys.md)
- [Integration quickstart](https://m7.org/docs/api/sso.user.m7.org/quickstart.md)
- [Provider profile](https://m7.org/docs/api/sso.user.m7.org/provider-profile.md)
- [M7 Identity SDK and current downloads](https://m7.org/docs/sdk/m7-identity/)

Live discovery supplies endpoint locations and advertised capabilities. Use the
provider profile for the integration contract and current testing status.
<!-- m7-identity-discovery:end -->

M7 Identity SDK provides integration packages for adding M7 sign-in,
session handling, token validation, and live identity operations to applications
and operational processes.

Choose the integration subject that matches where the identity work runs:

| Subject | Use it when | Current implementation |
| --- | --- | --- |
| [Website integration](https://m7.org/docs/sdk/m7-identity/website/) | A browser-facing PHP application needs M7 login and a same-origin session bridge, or its backend needs to validate incoming M7 tokens. | `web-php` 0.1.4 and `token-php` 0.1.3 stable releases |
| [CLI and background processes](https://m7.org/docs/sdk/m7-identity/cli/) | A PHP command, worker, scheduler, or operational process needs to validate or acquire a token, send an authenticated resource request, or call supported live identity operations. | `token-php` 0.1.3 and `cli-php` 0.1.2 stable releases |

Each section describes consumer capabilities and installation by subject. The
package names identify the current implementation; they do not define the
long-term documentation structure. Language-specific pages can be added below
these subjects when another supported implementation is released.

<!-- KEEP: download table. Duplicated from /docs so Get the SDK lands on zips. Preserve across #makedocs push. -->

## M7 Identity SDK downloads

Currently published development-access PHP releases, verified on 2026-09-21:

| Package | Version | Downloads |
| --- | --- | --- |
| Web/PHP | 0.1.4 | [ZIP](https://m7.org/downloads/m7-identity/web-php/0.1.4/m7-identity-web-php-0.1.4.zip) · [SHA-256](https://m7.org/downloads/m7-identity/web-php/0.1.4/m7-identity-web-php-0.1.4.zip.sha256) · [Manifest](https://m7.org/downloads/m7-identity/web-php/0.1.4/m7-identity-web-php-0.1.4.zip.manifest.json) |
| Token/PHP | 0.1.3 | [ZIP](https://m7.org/downloads/m7-identity/token-php/0.1.3/m7-identity-token-php-0.1.3.zip) · [SHA-256](https://m7.org/downloads/m7-identity/token-php/0.1.3/m7-identity-token-php-0.1.3.zip.sha256) · [Manifest](https://m7.org/downloads/m7-identity/token-php/0.1.3/m7-identity-token-php-0.1.3.zip.manifest.json) |
| CLI/PHP | 0.1.2 | [ZIP](https://m7.org/downloads/m7-identity/cli-php/0.1.2/m7-identity-cli-php-0.1.2.zip) · [SHA-256](https://m7.org/downloads/m7-identity/cli-php/0.1.2/m7-identity-cli-php-0.1.2.zip.sha256) · [Manifest](https://m7.org/downloads/m7-identity/cli-php/0.1.2/m7-identity-cli-php-0.1.2.zip.manifest.json) |

Verify each ZIP against its SHA-256 sidecar before extraction. CLI/PHP 0.1.2 requires Token/PHP >=0.1.3 <0.2.0.

### Get started

- [Install M7 Identity SDK for a website](https://m7.org/docs/sdk/m7-identity/website/installation.md)
- [Install M7 Identity SDK for CLI and background processes](https://m7.org/docs/sdk/m7-identity/cli/installation.md)

The SDK packages are distributed under MTL-10. Packagist installation is not currently available.

## Package and release status

The published ZIPs and every SHA-256 and manifest sidecar match the reviewed
release artifacts. Package `VERSION`, metadata, archive contents and annotated
source tags identify the same versions:

| Package | Current release | Source tag |
| --- | --- | --- |
| `web-php` | 0.1.4 | `web-php-v0.1.4` |
| `token-php` | 0.1.3 | `token-php-v0.1.3` |
| `cli-php` | 0.1.2, requiring `token-php >=0.1.3 <0.2.0` | `cli-php-v0.1.2` |

All nine current download files were retrieved from m7.org and verified against
those artifacts. Install using the matching links and commands below; older
published versions remain immutable. Composer repository publication is
separate from these public ZIP downloads, and Packagist remains unavailable.

Preparation of Token/PHP 0.1.3, Web/PHP 0.1.4 and CLI/PHP 0.1.2 verified
checksums, clean extraction, byte-identical rebuilds, conformance, PHP lint,
autoloading and package hygiene. The token suite passed 155 tests with native
crypto and 134 without it; the CLI suite passed 64 tests. Isolated local
Composer consumer checks also passed without the native extension. These are
artifact and local-install checks, not installation from published Composer
tags or a new production acceptance campaign. Packagist remains unavailable.

### Optional native runtime

The Identity SDK artifacts contain the PHP integration with M7 Crypto. Install
the separate M7 C Crypto library and M7 PHP Crypto compiled extension only for
features that need them; they are not bundled SDK binaries. Their current
0.3.0 source candidates have a separate build and distribution lifecycle.

For a complete server procedure, follow the
[AlmaLinux C/PHP installation walkthrough](https://m7.org/docs/sdk/m7-php-crypto/integration/almalinux.md).
The SDK detects the extension once it is loaded in the application's PHP process
and uses it for configured native operations. Installation does not change
`allowed_algs`, supply keys or enable response encryption; those remain explicit
application policies. PHP 8.5 is not an alternative backend in the current SDK;
the guide describes a [possible custom port](https://m7.org/docs/sdk/m7-php-crypto/integration/almalinux.md#a-possible-custom-php-85-port)
without claiming full M7 Crypto parity.

Use the maintained component guides for native setup and support status:

| Component | Integration and installation | Release status |
| --- | --- | --- |
| [M7 C Crypto](https://m7.org/docs/sdk/m7-c-crypto/) | [C API and ownership](https://m7.org/docs/sdk/m7-c-crypto/integration/README.md) · [Build and install the C library first](https://m7.org/docs/sdk/m7-c-crypto/integration/installation.md) | [C releases and integrity](https://m7.org/docs/sdk/m7-c-crypto/releases.md) |
| [M7 PHP Crypto](https://m7.org/docs/sdk/m7-php-crypto/) | [PHP API and errors](https://m7.org/docs/sdk/m7-php-crypto/integration/README.md) · [Build the extension against that C library](https://m7.org/docs/sdk/m7-php-crypto/integration/installation.md) | [PHP releases and integrity](https://m7.org/docs/sdk/m7-php-crypto/releases.md) |

The initial validated native target is PHP **8.4 NTS**. The wrapper's PHP 8.4+
header requirement does not establish support for every later PHP version or
ZTS build, and the base SDK's PHP 8.1+ requirement does not extend native
compatibility. Broader native PHP support is later work. The linked guides
distinguish verified 0.3.0 candidates from final/public releases; linking their
documentation does not announce new crypto downloads or change SDK artifacts.

| Selected capability | Runtime requirement |
| --- | --- |
| Base SDK and ordinary supported PHP OpenSSL signing | PHP 8.1+, OpenSSL; Web/PHP also requires cURL. No M7 Crypto dependency. |
| Additional native signature profiles and local HMAC verification | Compatible M7 PHP Crypto extension, separate C library and algorithm provider; the current wrapper targets PHP 8.4+. |
| Encrypted ID tokens, JARM and signed UserInfo | PHP 8.4+, M7 PHP Crypto 0.3+, matching M7 C Crypto 0.3+, and PHP OpenSSL AES-GCM. |

`ext-m7crypto` is an optional Composer suggestion. Broader native PHP
compatibility is deferred and does not block base SDK installation. See the
[recipient runtime checks](https://m7.org/docs/sdk/m7-identity/response-encryption.md#runtime-and-installation)
before enabling encryption in the actual application worker.

## Token Exchange and target claims in current source

For delegated service access, updated Token/PHP and CLI/PHP source provide
[`tokenExchange()` and `m7-identity token-exchange`](https://m7.org/docs/sdk/m7-identity/cli/token-exchange.md).
This RFC 8693 operation is separate from refresh exchange. Current Token/PHP
also supports the optional nested `m7.target_client_id` validation policy:
`client_id` identifies the requesting app, while the nested claim identifies
the receiving app. See the [exchange and claim examples](https://m7.org/docs/sdk/m7-identity/cli/token-exchange.md#refresh-and-validate-the-target-bundle).
These additions are included in Token/PHP 0.1.3 and CLI/PHP 0.1.2. Install
both matching packages and verify their checksums; a version label alone does
not establish contents.

## Additional signing profiles in current source

The updated `token-php` source supports all 15 asymmetric signing profiles:
RS256/384/512, PS256/384/512, ES256/384/512, ES256K, Ed25519, Ed448 and
ML-DSA-44/65/87. Existing RSA and ES256/P-256 JWK verification retain PHP
OpenSSL. Additional profiles, including ES256 with a PEM key, use the optional
`m7crypto` extension and `M7\Crypto\Key` through the separate C library.

Use an explicit `allowed_algs` policy; its SDK default remains `['RS512']`.
Native profiles require a compatible OpenSSL provider and resolved SPKI public
PEM through the existing provided-PEM or trusted `x5u` path. RSA-PSS also accepts
the existing RSA JWK verification key. This source change does not add
EC/OKP/AKP JWKS decoders or new UserInfo algorithms. Signed UserInfo remains
RS256/RS512. HMAC uses the separate explicit-secret policy below; it does not
add an automatic shared-secret resolver.

If a selected algorithm needs the native backend and it is absent or cannot
perform the operation, verification fails explicitly. The low-level verifier
throws `SignatureVerificationException`; the facade returns its existing
unsuccessful validation report. Signature checking is never skipped. Local
issuer, audience, time, scope, DPoP and trusted-key policies still apply.

The source was deployed for M7's USER/API.USER integration and Ed25519 browser
login and refresh were confirmed by the operator. Native verification tests
cover all 15 profiles. Token/PHP 0.1.3 includes this integration; the
earlier Token/PHP 0.1.2 ZIP remains unchanged. Native component packaging has
its own lifecycle and does not block ordinary Identity SDK installation. The
currently documented crypto wrapper targets PHP 8.4+; do not infer support for
every PHP version accepted by the base Identity SDK. ML-DSA needs an available
provider implementation (OpenSSL 3.5+ in the tested deployment).

## HMAC in current source

Current Token/PHP source verifies HS256, HS384 and HS512 using an explicit
`hmac_secret`, `allowed_algs`, the m7crypto extension and `M7\Crypto\Key`.
Token/PHP 0.1.3 includes this addition; the earlier Token/PHP 0.1.2
ZIP does not. The current native wrapper targets PHP 8.4+; the base SDK's lower PHP requirement does not
extend the wrapper's compatibility.

After loading the current Token/PHP autoloader, supply trusted policy:

```php
use M7\Identity\M7IdentitySDK;

// Values come from trusted server configuration, never the JWT header.
$report = (new M7IdentitySDK())->validate($accessToken, [
    'allowed_algs' => ['HS512'],
    'hmac_secret' => $originalClientSecret,
    'issuer' => 'https://sso.user.m7.org',
    'audience' => 'https://api.example.com',
    'client_id' => $expectedClientId,
]);
```

The default allowlist remains `['RS512']`. Set the expected HS algorithm
explicitly. Minimum original-secret lengths are 32 bytes for HS256, 48 for
HS384 and 64 for HS512; the verifier accepts at most 4096 bytes. Pass original
bytes without hashing, trimming or base64-decoding. Select the client and
secret from trusted configuration, not solely from unverified token claims.
`hmac_secret` is separate from OAuth request authentication's
`auth.client_secret`; acquiring or refreshing a token does not automatically
run local MAC verification.

Missing native support, missing/short secrets, disallowed algorithms,
wrong secrets and altered signatures fail closed. The facade returns an
unsuccessful validation report; low-level verification errors throw. HMAC
never falls back to a certificate. Secrets are not fetched through JWKS, PEM
or `x5u`; HMAC headers containing `x5u`, `jku`, `jwk` or `k` are rejected.
Keep time, issuer, audience, scope, principal and sender-constraint policies,
including request-bound DPoP when required. ID tokens need the relying-party
client-ID audience and transaction nonce and are not API access credentials.
Treat refresh tokens as opaque client state.

A secret holder can both verify and create MACs. Local verification alone
therefore does not prove provider issuance or active state. Resource servers
must retain authoritative issued-token/state checks, such as applicable
SSO introspection, and their resource authorization policy. Auth method `none`
does not gain confidential introspection access by storing an HMAC secret.
Public clients must use asymmetric ID-token signing. The User.M7/SSO update
blocks `none` with HS256/384/512. The September 20 production checks passed
canonical registration and runtime rejection for all three algorithms. A
separate final browser check confirmed the deployed form behavior and an HS512
Basic-authentication secret reset followed by successful token issuance and
MAC verification. Legacy-value guards passed an isolated check using the
deployed module; no persisted production legacy registration or repair was
tested. SDK MAC verification remains available, but cannot make an ineligible
SSO client configuration valid. Existing legacy clients need explicit
confidential-client repair, never a secret embedded in a public application.

The Web/PHP session bridge uses authenticated SSO introspection. Its HMAC
browser login, profile and refresh path does not require m7crypto. Keep the
OAuth client secret on the PHP server, never in browser JavaScript, URLs or
session cookies. The same original secret serves HMAC and secret-based client
authentication when both apply. First save confidential-client authentication
for a client that can protect its credentials, then save the HMAC algorithm
and set/reset its secret. Existing password hashes cannot be recovered.
Retain an old secret
while accepting tokens issued with it. See [SSO HMAC setup](https://m7.org/docs/api/sso.user.m7.org/registration#hmac-token-signing).

The September 2026 current-source campaign passed HS256/384/512 browser
sign-in, profile and strict refresh with PAR, authorization code, PKCE and
browser DPoP. All three also passed server client-credentials and
consumer device/strict-refresh campaigns. The HS256 device case used `none`;
it remains historical signing evidence and is excluded by the eligibility
policy above. Browser acceptance used a confidential PHP backend, not a
JavaScript client holding a secret. The separate native Token/PHP check
verified live HS512 access/refresh JWTs and rejected wrong-secret,
disallowed-algorithm and tampered-signature cases. The full native Token SDK
suite at that campaign passed 139 tests with 1133 assertions. The later release
checks are recorded above. Neither result establishes public distribution,
every live auth/rotation combination, or formal OpenID conformance. UserInfo's
RS256/RS512 contract remains unchanged.

### Post-quantum use and the Web SDK

The tested device-code pickup/refresh and machine-token flows can use ML-DSA
with a compatible native verifier and suitably sized storage and transports.
Device approval happens in a browser, but the relying client's token package
is returned to the device process as JSON.

The current Web/PHP integration stores complete access and refresh JWTs in
single cookies. **Do not select ML-DSA for this browser session path yet.**
ML-DSA-65/87 encoded signatures alone exceed Chromium's 4,096-byte cookie
name-plus-value limit; ML-DSA-44 can exceed it once the JWT header and claims
are included. The native verifier working does not prove cookie acceptance.
Total Cookie/Authorization headers and proxy/storage limits also matter.
See the [Chromium cookie-size contract](https://chromium.googlesource.com/chromium/src/net/%2B/refs/heads/main/cookies/parsed_cookie.h).

Server-held tokens with an opaque browser session reference are a proposed
follow-up, not current SDK behavior. Ed25519 provides the accepted compact
browser test profile. Retain the existing published-release capabilities until
updated source or a verified new artifact is installed.

## Current boundaries

The website package supplies a PHP backend-for-frontend integration for browser
authorization and sessions. The token package supplies a PHP library for local
validation, confidential-client token acquisition, online introspection, and
UserInfo operations. It also supplies public/confidential
device authorization, one-attempt token pickup, complete refresh-package
exchange and acknowledgement, and schema-neutral authenticated resource
requests.

The separate `cli-php` package is the dedicated `m7-identity`
executable adapter over `token-php`. Its supported command families are `app`,
`profile`, `password`, `token`, `client-credentials`, `device-code`, `exchange`,
`ack`, `ensure`, and authenticated resource `request`. The adapter owns
terminal prompting, device polling, command output and exit status, and
protected keychain persistence. The storage-neutral token library owns the
protocol operations and returns reports and complete bundles without choosing
CLI input, output, or storage. The CLI release verifier exercises the packaged
command against its matching token dependency. CLI/PHP 0.1.2 adds
RFC 8693 `token-exchange` and is verified with Token/PHP 0.1.3.

Neither layer currently supplies authorization-code acquisition or outbound
DPoP proof generation. Callers of DPoP-bound operations must provide a fresh
externally generated proof for each applicable request.

## Encrypted responses

Web/PHP 0.1.4 and Token/PHP 0.1.3 include optional JWE receiving support
with scoped live acceptance. Matching immutable archives and sidecars are
available above. Earlier package versions do not gain this capability.
See [receiving encrypted responses](https://m7.org/docs/sdk/m7-identity/response-encryption.md) before selecting an
SDK build for an application requiring encryption.

## Security

Use HTTPS, verify release checksums before installation, and keep access tokens,
refresh credentials, client secrets, DPoP proofs, session cookies, and
deployment keys out of source control, URLs, command histories, logs, and
public documentation.

Report private security issues to [security@m7.org](mailto:security@m7.org).
Commercial licensing inquiries may be sent to
[legal@m7.org](mailto:legal@m7.org).

- [Receiving encrypted PHP SDK responses](https://m7.org/docs/sdk/m7-identity/response-encryption.md): optional PHP
  recipient setup, optional native dependencies, validation, rotation and tested
  acceptance status. The dated live campaigns and release package checks
  retain their documented feature and runtime boundaries.
