Class: Safire::Protocols::Udap Private

Inherits:
Object
  • Object
show all
Includes:
Behaviours
Defined in:
lib/safire/protocols/udap.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Note:

For internal use by Client only.

UDAP Security STU2 protocol implementation.

Handles server metadata discovery from the UDAP well-known endpoint (per STU2 §2). Results are cached per community within each instance.

All other UDAP flows (B2B client credentials, B2C authorization code, Tiered OAuth, Dynamic Client Registration) raise NotImplementedError and are planned for future PRs.

This is an internal class used exclusively by Client. Do not instantiate it directly — use Client instead.

Constant Summary collapse

WELL_KNOWN_PATH =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

'/.well-known/udap'.freeze

Instance Method Summary collapse

Methods included from Behaviours

#authorization_url, #refresh_token, #register_client, #request_access_token, #request_backend_token, #token_response_valid?

Constructor Details

#initialize(config) ⇒ Udap

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Udap.



23
24
25
26
27
# File 'lib/safire/protocols/udap.rb', line 23

def initialize(config)
  @base_url       = config.base_url
  @http_client    = Safire::HTTPClient.new
  @metadata_cache = {}
end

Instance Method Details

#server_metadata(community: nil, trusted_anchors: [], crls: [], revocation_checker: nil, verify_chain: true) ⇒ Safire::Protocols::UdapMetadata

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Retrieves and parses UDAP server metadata from the well-known endpoint.

When a community URI is provided, the request is scoped to that community by appending ?community=<encoded-uri> to the endpoint URL. Results are cached per community — subsequent calls with the same community return the cached result without a second HTTP request, as long as its signed_metadata still validates against the current trust policy.

The signed_metadata JWT in the discovery response is validated per UDAP Security STU2. Signed endpoint claims (+token_endpoint+, registration_endpoint, and optionally authorization_endpoint) are merged over the unsigned values before the metadata object is constructed.

Parameters:

  • community (String, nil) (defaults to: nil)

    optional UDAP community URI; scopes discovery

  • trusted_anchors (Array<OpenSSL::X509::Certificate>) (defaults to: [])

    X.509 trust anchors for signed_metadata chain verification; required for production use

  • crls (Array<OpenSSL::X509::CRL>) (defaults to: [])

    certificate revocation lists for production chain validation

  • revocation_checker (#call, nil) (defaults to: nil)

    custom revocation policy; must return true to pass

  • verify_chain (Boolean) (defaults to: true)

    when false, skips X.509 chain validation (dev/test only)

Returns:

Raises:



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/safire/protocols/udap.rb', line 54

def (community: nil, trusted_anchors: [], crls: [], revocation_checker: nil, verify_chain: true)
  community = normalize_community(community)
  trust_policy = {
    trusted_anchors:,
    crls:,
    revocation_checker:,
    verify_chain:
  }
  cache_key = build_cache_key(community, trusted_anchors, crls, revocation_checker, verify_chain)
  cached_entry = @metadata_cache[cache_key]
  return cached_entry.fetch(:metadata) if cached_entry && cached_entry_valid?(cached_entry, trust_policy)

  @metadata_cache.delete(cache_key)

  entry = (
    community:,
    trust_policy:
  )
  @metadata_cache[cache_key] = entry
  entry.fetch(:metadata)
end