OAuth and OIDC Provider Metadata Vendor-Intake Gate avatar

OAuth and OIDC Provider Metadata Vendor-Intake Gate

Pricing

from $10.00 / 1,000 run_starts

Go to Apify Store
OAuth and OIDC Provider Metadata Vendor-Intake Gate

OAuth and OIDC Provider Metadata Vendor-Intake Gate

Writes the security opinion that a vendor-intake review needs before a company connects to a SaaS vendor, an identity provider or a remote MCP server. For each issuer that you name, the Actor reads the public OpenID Connect Discovery or RFC 8414 metadata

Pricing

from $10.00 / 1,000 run_starts

Rating

0.0

(0)

Developer

kingii98

kingii98

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

9 days ago

Last modified

Categories

Share

Write the security opinion that a vendor-intake review needs, before your company connects to a SaaS vendor, an identity provider or a remote MCP server.

You give a list of issuer base URLs. For each issuer the Actor reads the public OpenID Connect Discovery or RFC 8414 metadata document, the published JSON Web Key Set, and the RFC 9728 protected-resource metadata, and it reads the dynamic client registration endpoint. It then gives you one dataset row for each issuer with the endpoints, the declared flows, the key-set defects, a list of findings and an A to F risk grade. Attach that row to your review ticket as the evidence of your written opinion.

The Actor reads public metadata only

  • Every request is a GET.
  • The Actor sends no credential and no client identifier.
  • The Actor starts no login flow.
  • The Actor never sends a POST to the registration endpoint, so it never registers a client at the vendor. The registration probe is a plain read that only shows whether the endpoint answers a stranger.
  • Only HTTPS is allowed. A URL that carries credentials is refused. A host that resolves to a loopback, private, link-local or otherwise reserved address is refused, and each redirect hop passes the same guard again.
  • A refused issuer line does not stop the run. It gets its own dataset row with the finding OIDC-DISCOVERY-UNREACHABLE, it is not charged, and the run audits every other line of the list and ends with SUCCEEDED.
  • No browser, no proxy, no external database and no paid API.

Input

Run the Actor with an empty input to audit the three public identity providers of the default fixture. Every field below has a default.

FieldTypeDefaultWhat it does
issuersarray of stringsthree public issuers1 to 200 issuer base URLs, for example https://accounts.google.com, or full .well-known metadata URLs. For a base URL the Actor tries the OpenID Connect Discovery path and the RFC 8414 path in turn and keeps the first document that parses. Repeated URLs are read once.
checksarray of stringsevery groupThe groups of rules to apply. See the table below.
baselineKeystring"" (empty)Optional name of a stored snapshot, for example Q3 vendor review. Set it to get the changed_since_baseline flag. Leave it empty for a single audit with no stored state. Any name works: the run makes it safe as a record name (see below).
requestTimeoutSecondsinteger15How long one HTTPS request may take. Allowed range 5 to 60.

Check groups

GroupWhat it examines
metadataThe document is reachable, is valid JSON, and its issuer field names the audited URL. This group is always on, because every other group reads the fields of this document.
transportEvery endpoint URL is HTTPS, and the metadata was served over TLS 1.2 or later.
pkceS256 is declared, and the weak plain method is not offered.
grantsNo implicit or hybrid flow, so no token travels in a URL.
client_authThe token endpoint does not accept the none client authentication method.
jwksThe key set is reachable and holds no short RSA key, no unapproved curve, no shared secret, no private key material and no expired certificate.
registrationWhether the dynamic client registration endpoint answers an anonymous read.
resource_metadataWhether the issuer publishes RFC 9728 protected-resource metadata.
endpointsWhether the authorization, token, revocation and introspection endpoints are named.

Switching a group off also stops the requests that only that group needs. Without jwks the Actor does not read the key set, without registration it does not probe the registration endpoint, and without resource_metadata it does not look for the protected-resource document.

Output

The dataset holds one row for each issuer, then one summary row. The row_type field tells the two apart.

Issuer row (row_type: "issuer")

issuer, discovery_url, http_status, metadata_valid_json, issuer_matches_url, tls_version, endpoints (an object with authorization, token, jwks, registration, revocation and introspection), endpoints_https_only, pkce_s256_supported, plain_pkce_offered, response_types_supported, implicit_grant_offered, token_endpoint_auth_methods, none_auth_method_offered, jwks_reachable, jwks_key_count, weak_or_expired_key_flags, dynamic_client_registration_open, protected_resource_metadata_present, findings (each with rule_id, severity, message and evidence_field), finding_count, highest_severity, risk_grade, changed_since_baseline, baseline_changes, unreachable and note.

Summary row (row_type: "summary")

issuers_requested, issuers_audited, issuers_with_high_severity, findings_by_rule, unreachable_issuers, issuers_changed_since_baseline, grades, baseline_key, checks and note.

issuers_requested counts the issuers that you gave. issuers_audited counts only the issuers that returned a metadata document that the rules could read, so it always matches the number of issuer_audited events that the run charges. The rest of the issuers are named in unreachable_issuers.

Risk grade

GradeMeaning
FTwo or more high-severity findings.
EOne high-severity finding.
DThree or more medium-severity findings.
COne or two medium-severity findings.
BOnly low-severity findings.
ANo finding.

Changed since the last review

Give a baselineKey, for example q3-vendor-review. The Actor stores one small snapshot for each issuer under that name, and it compares the next run against it. The snapshot holds the endpoints, the declared methods, the key identifiers and the rule identifiers that fired.

  • On a first run there is nothing to compare against, so changed_since_baseline is null. That is normal and is not a defect.
  • On a later run changed_since_baseline is true or false, and baseline_changes names the fields that moved.
  • The name is only a record name in a key-value store. The run replaces every character that is not a letter, a digit, a dot, a dash or an underscore with a dash, and it keeps the first 60 characters. Q3 vendor review therefore becomes Q3-vendor-review. The summary row reports the name that the run used, so give the same name again at the next review.

Version 1 works with no stored state, because a single audit already gives you the review artefact.

A business verdict never fails the run

A failed gate, an unreachable vendor, a vendor without a valid discovery document and a run with no finding are all results of this product. Each one is a dataset row plus a run status message, and the run ends with SUCCEEDED. Only a real malfunction, such as an input that cannot be parsed, gives a FAILED run.

Pricing

The Actor uses the pay-per-event model. It charges these three events.

EventUnitPrice (USD)When it is charged
run_startper run0.01Once for each run, after the input parses.
issuer_auditedper issuer metadata set read and audited0.015Once for each issuer that returned a valid metadata document. An issuer that gave no valid document was not audited, so it is not charged.
baseline_change_reportedper issuer that differs from its stored baseline0.01Only when you give a baselineKey and the issuer really moved. A first run and an unchanged issuer are not charged.

The default maximum total charge for one run is 10 USD, which covers a vendor portfolio of about 600 issuers.

Limits

LimitValue
Issuers in one run1 to 200
Requests for each issuerabout 6 to 10 small GET requests
Issuers read at one time5, so the Actor does not load the vendor
Request timeout5 to 60 s, default 15 s
Redirect hops for one fetch3, and each hop passes the public-target guard
Response body read512 KiB, and a larger body is not parsed
Baseline namemade safe, then cut to 60 letters, digits, dots, dashes or underscores

Development

uv sync
uv run pytest
uv run ruff check .