Matrix Well-Known Federation & Client Auditor avatar

Matrix Well-Known Federation & Client Auditor

Pricing

Pay per usage

Go to Apify Store
Matrix Well-Known Federation & Client Auditor

Matrix Well-Known Federation & Client Auditor

Deep audit of a Matrix homeserver's /.well-known/matrix/server and /.well-known/matrix/client discovery files. Validates m.server host:port syntax, optional federation port reachability, client base_url reachability, and CORS.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Sanskar Jaiswal

Sanskar Jaiswal

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Audits a Matrix homeserver's service-discovery files per the Matrix specification: /.well-known/matrix/server (Server-Server API federation delegation) and /.well-known/matrix/client (Client-Server API client discovery). Matrix is the open federated chat protocol behind Synapse, Dendrite, Conduit, and clients like Element. Misconfigured delegation is a frequent self-hosting support problem: wrong port, unreachable federation target, malformed host:port syntax, missing CORS on the client file, http:// instead of https:// in the homeserver base_url, or a client base_url that does not actually serve the Matrix client API.

Use cases

  • Matrix homeserver operators (Synapse, Dendrite, Conduit) verifying federation delegation before going live or after a server move.
  • Infrastructure and DevOps teams debugging "federation not working" or "client can't log in" reports.
  • Agency and consultant audits of a client's self-hosted Matrix deployment.
  • CI/CD pipelines validating /.well-known/matrix/* after reverse-proxy or DNS config changes.
  • Protocol tooling and client developers checking real-world homeserver well-known behavior against the spec.

Input

FieldTypeRequiredDescription
serverNamestringyesThe Matrix server_name (base domain) to audit, e.g. matrix.org.
checkFederationReachabilitybooleannoIf true (default), attempts an HTTPS GET to https://<resolved host>:<resolved port>/_matrix/key/v2/server using the host:port parsed from m.server, to confirm federation is actually reachable.
checkClientApiReachabilitybooleannoIf true (default), attempts an HTTPS GET to <homeserver base_url>/_matrix/client/versions to confirm the declared client base URL actually serves the Matrix Client-Server API.
timeoutSecondsintegernoRequest timeout, 3-30 seconds. Default 10.

Output

One JSON object per run, pushed to the default dataset.

FieldTypeDescription
serverNamestringThe audited server_name.
checkedAtstringISO timestamp of the audit.
serverobjectAnalysis of /.well-known/matrix/server (see below).
clientobjectAnalysis of /.well-known/matrix/client (see below).
scoreintegerReadiness score, 0-100. The server half and client half are each capped at 50 points independently before being summed, so a perfect federation setup with a broken client file (or vice versa) cannot silently score above 50.
gradestringLetter grade, A+ to F.
issuesarrayCombined, deduplicated issue descriptions from both halves.
recommendationsarrayCombined actionable fixes, citing the specific Matrix spec requirement.

server object

FieldTypeDescription
urlstringThe /.well-known/matrix/server URL that was fetched.
finalUrlstringFinal URL after following any redirects.
httpStatusinteger|nullHTTP status code.
httpsbooleanWhether served over HTTPS.
contentTypestring|nullContent-Type response header value.
foundbooleanWhether a 200 response was served.
jsonValidbooleanWhether the body parses as valid JSON.
parseErrorstring|nullJSON parse error, if any.
mServerRawstring|nullThe raw m.server value from the JSON body.
mServerHoststring|nullParsed host from m.server.
mServerPortinteger|nullParsed explicit port from m.server, or null if the default (8448) applies.
hostFormatValidbooleanWhether m.server is syntactically a valid host[:port] value per the spec.
isIpLiteralbooleanWhether the host is an IPv4/IPv6 literal rather than a hostname.
federationReachableboolean|nullWhether /_matrix/key/v2/server responded at the delegated host:port. null if the check was disabled or not applicable.
federationCheckErrorstring|nullError from the federation reachability check, if any.
issuesarrayIssues specific to the server well-known file.

client object

FieldTypeDescription
urlstringThe /.well-known/matrix/client URL that was fetched.
finalUrlstringFinal URL after following any redirects.
httpStatusinteger|nullHTTP status code.
httpsbooleanWhether served over HTTPS.
contentTypestring|nullContent-Type response header value.
foundbooleanWhether a 200 response was served.
jsonValidbooleanWhether the body parses as valid JSON.
parseErrorstring|nullJSON parse error, if any.
homeserverBaseUrlstring|nullThe m.homeserver.base_url value.
homeserverBaseUrlHttpsbooleanWhether base_url uses https://.
identityServerBaseUrlstring|nullThe m.identity_server.base_url value, if present.
identityServerPresentbooleanWhether the optional m.identity_server member is present.
corsAllowOriginstring|nullThe Access-Control-Allow-Origin header value on the client well-known response, if present.
corsOkbooleanWhether CORS is permissive (* or matches the server's own origin).
clientApiReachableboolean|nullWhether <base_url>/_matrix/client/versions responded. null if the check was disabled or not applicable.
clientApiCheckErrorstring|nullError from the client API reachability check, if any.
issuesarrayIssues specific to the client well-known file.

Example input

{
"serverName": "matrix.org",
"checkFederationReachability": true,
"checkClientApiReachability": true,
"timeoutSeconds": 10
}

Example output

{
"serverName": "matrix.org",
"checkedAt": "2026-10-08T12:00:00.000Z",
"server": {
"url": "https://matrix.org/.well-known/matrix/server",
"https": true,
"httpStatus": 200,
"found": true,
"jsonValid": true,
"mServerRaw": "matrix-federation.matrix.org:443",
"mServerHost": "matrix-federation.matrix.org",
"mServerPort": 443,
"hostFormatValid": true,
"isIpLiteral": false,
"federationReachable": true,
"issues": []
},
"client": {
"url": "https://matrix.org/.well-known/matrix/client",
"https": true,
"httpStatus": 200,
"found": true,
"jsonValid": true,
"homeserverBaseUrl": "https://matrix-client.matrix.org",
"homeserverBaseUrlHttps": true,
"identityServerPresent": true,
"corsOk": true,
"clientApiReachable": true,
"issues": []
},
"score": 100,
"grade": "A+",
"issues": [],
"recommendations": ["Matrix well-known federation and client discovery look spec-conformant. Re-run this audit after homeserver upgrades to catch regressions."]
}

What the spec requires

Per the Matrix specification:

  • /.well-known/matrix/server lets a homeserver delegate federation traffic to a different host and/or port than its server_name. The body is JSON {"m.server": "<hostname>[:<port>]"}; if the port is omitted, federation traffic defaults to port 8448. IPv6 literal hosts must be bracketed ([::1]:8448).
  • Other homeservers resolve server_name by checking this well-known file first (falling back to SRV records, then the default port) and must be able to reach /_matrix/key/v2/server at the resolved authority.
  • /.well-known/matrix/client lets clients (Element, other apps) discover the homeserver's Client-Server API base URL without the user typing it manually. The body is JSON {"m.homeserver": {"base_url": "https://..."}, "m.identity_server": {"base_url": "https://..."}}; m.identity_server is optional.
  • The declared base_url should actually serve /_matrix/client/versions; a well-known file pointing at a non-functioning base URL breaks client auto-discovery even though the file itself looks correct.
  • Since the client well-known file is fetched by browser-based clients (Element Web) from a different origin, the spec expects a permissive Access-Control-Allow-Origin header so those clients can read it cross-origin.

Security

  • Public HTTP/HTTPS only. URL credentials are rejected.
  • Localhost and private/link-local IPv4 and IPv6 literal ranges (including bracketed IPv6 literals) are blocked.
  • Hostnames are DNS-resolved and resolved addresses are re-checked against the same private-range rules before any request is made (SSRF defense in depth).
  • This guard is applied both to the two well-known fetches on serverName AND to the federation/client targets parsed out of those files' JSON content, since those are server-controlled secondary fetch targets and the single most important security control in this actor.
  • Redirects are manually followed and each hop is revalidated with the same SSRF checks before the next request is made (max 3 hops).
  • Response bodies are capped at 1 MB.
  • Only four URLs are ever fetched: the two well-known files on serverName, and (if enabled) the federation key endpoint at the host:port declared inside the server well-known file and the client versions endpoint at the base_url declared inside the client well-known file. No other links are followed.
  • No login, no credential collection, no private-data extraction.

Pricing

EventPrice (USD)
Actor start$0.005
Domain audited$0.01

Apify takes a 20% platform commission; the operator keeps 80%.

FAQ

What happens if both well-known files are missing? The audit still completes and returns a low score with a missing status on the endpoint checks. Federation can still work via SRV record fallback or the default port 8448, so a missing well-known file is not an automatic hard failure, but it is flagged as a recommendation since well-known delegation is the spec's preferred, more flexible mechanism.

Why are the server and client scores capped independently before being summed? So that a homeserver with perfect federation delegation but a broken or missing client well-known file (or vice versa) cannot score above 50/100. Each half contributes at most 50 points regardless of how well the other half performs.

Does this actor fetch arbitrary URLs found in the response? No. It only ever fetches the two well-known URLs on the audited serverName, plus the federation key endpoint and client versions endpoint derived specifically from m.server and m.homeserver.base_url — both of which are re-validated through the same SSRF guard used on the primary input before being fetched.

Why does this actor exist when generic well-known probers already check these paths? Existing bulk well-known probers on Apify Store check dozens of well-known paths shallowly and report only found/not-found. They do not validate m.server host:port syntax, do not test federation port reachability, do not confirm the client base_url actually serves the Matrix client API, and do not check CORS on the client file. This actor does one deep, spec-grounded audit of the Matrix well-known files specifically.