Portal Community

What Is a Relying Party?

In SSO terminology, a Relying Party (RP) is an application that trusts Passport to authenticate users on its behalf. For SAML this is called a Service Provider (SP); for OIDC it is called a Client. Passport uses the term Consumer Registration internally to represent either type uniformly.

Every consumer registration is tenant-scoped. A registration in tenant-A cannot be used by users from tenant-B. The consumerKey is a URL-safe string that uniquely identifies the registration within a tenant.

Consumer Registration Fields

FieldTypeDescription
consumerKeystringURL-safe unique identifier, e.g., salesforce-prod
protocolenumSAML2, OIDC, or DiscourseConnect
displayNamestringFriendly name shown in audit logs and admin UI
entityIdstringSAML Entity ID of the SP (SAML only)
acsUrlstringSAML Assertion Consumer Service URL
redirectUrisstring[]OIDC allowed redirect URIs — exact match enforced
allowedScopesstring[]OIDC scopes this client may request
signingSecretstringDiscourseConnect shared secret (DiscourseConnect only)
requireSignedRequestsboolSAML — require signed AuthnRequests
requireMfaboolForce MFA before issuing assertion to this consumer
groupMappingsobjectMaps Passport role names → SP group names
assertionLifetimeSecondsintSAML assertion validity window (default 300)
tenantIdstringOwning tenant — enforced automatically

Registering a SAML Consumer

POST /passport/admin/consumers
Authorization: Bearer {admin-token}
Content-Type: application/json

{
  "consumerKey": "salesforce-prod",
  "protocol": "SAML2",
  "displayName": "Salesforce (Production)",
  "entityId": "https://bizfirst-dev-ed.my.salesforce.com",
  "acsUrl": "https://bizfirst-dev-ed.my.salesforce.com/saml/ssoinit/externalKey=BizFirstSSO",
  "nameIdFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
  "requireSignedRequests": true,
  "requireMfa": false,
  "assertionLifetimeSeconds": 300,
  "groupMappings": {
    "admin": "Salesforce_Admin",
    "manager": "Salesforce_Manager",
    "user": "Salesforce_Standard"
  },
  "tenantId": "tenant-abc"
}

Registering an OIDC Consumer

POST /passport/admin/consumers
Authorization: Bearer {admin-token}
Content-Type: application/json

{
  "consumerKey": "internal-portal",
  "protocol": "OIDC",
  "displayName": "Internal Employee Portal",
  "redirectUris": [
    "https://portal.internal.example.com/auth/callback",
    "https://portal.internal.example.com/auth/silent"
  ],
  "postLogoutRedirectUris": [
    "https://portal.internal.example.com/"
  ],
  "allowedScopes": ["openid", "profile", "email", "roles", "tenant"],
  "grantTypes": ["authorization_code", "refresh_token"],
  "requirePkce": true,
  "requireMfa": true,
  "accessTokenLifetimeSeconds": 900,
  "refreshTokenLifetimeSeconds": 604800,
  "tenantId": "tenant-abc"
}

Redirect URI Validation

Passport enforces exact match on redirect URIs. No wildcards, no path prefix matching. This prevents open redirect attacks where an authorization code could be delivered to a malicious URL.

Security: Exact URI Match

The redirect URI in the authorization request must exactly match one of the registered URIs — including scheme, host, port, and path. Query parameters in the registered URI are not supported. Register each environment (dev, staging, prod) as a separate consumer or add each URI individually.

Group and Role Mappings

The groupMappings field controls how Passport roles appear in assertions delivered to the consumer. This is important when the SP has its own role naming convention that differs from Passport's.

// groupMappings in consumer registration
"groupMappings": {
  "admin":        "SFDC_Sys_Admin",
  "manager":      "SFDC_Sales_Manager",
  "finance-user": "SFDC_Finance_Profile",
  "user":         "SFDC_Standard_User"
}

// Result in SAML assertion (user has roles: admin, finance-user)
<saml:Attribute Name="groups">
  <saml:AttributeValue>SFDC_Sys_Admin</saml:AttributeValue>
  <saml:AttributeValue>SFDC_Finance_Profile</saml:AttributeValue>
</saml:Attribute>

Consumer Cache

Consumer registrations are cached in-memory for 5 minutes. Changes made via the Admin API propagate to all Passport nodes within one cache cycle. For immediate propagation (e.g., disabling a compromised consumer), use the admin PURGE endpoint:

POST /passport/admin/consumers/{consumerKey}/purge-cache
Authorization: Bearer {admin-token}

// Response
{ "purged": true, "nodes": 3 }