pygamlastan.security¶
The Web Browser SSO validation suite, its configuration, the structured result, and the replay cache. See the Validation and replay protection guide.
- class pygamlastan.security.SecurityConfig¶
Controls which checks run and their tolerances. The default constructor uses production-safe defaults. Attributes are read/write properties.
- static permissive() SecurityConfig¶
Relaxed config for tests only. Never use in production.
- static strict() SecurityConfig¶
All checks enabled, including the optional ones.
- clock_skew_seconds: int¶
Tolerance, in seconds, applied to every time-window comparison (
NotBefore/NotOnOrAfter/ issue instants) to absorb clock drift.
- max_assertion_age_seconds: int¶
Reject an assertion whose
IssueInstantis older than this many seconds, independent of itsNotOnOrAfter(a freshness ceiling).
- require_signed_assertions: bool¶
Require each assertion to be individually signed (the common federation rule; SPs typically set
WantAssertionsSigned).
- require_signed_responses: bool¶
Require the enclosing
<Response>to be signed (in addition to, or instead of, signed assertions).
- require_encrypted_assertions: bool¶
Require assertions to arrive as
<EncryptedAssertion>(e.g. a PEFIM-style profile). Off by default.
- check_client_address: bool¶
Bind the assertion to the client’s source address (
SubjectConfirmationData/@Address). Requires passing the client address to validation. Off by default.
- enforce_persistent_id_uniqueness: bool¶
For a persistent
NameID, require apersistent_id_storeand reject a persistent identifier silently re-bound to a different principal (SAML erratum E78). On by default.
- reject_signatures_with_ds_object: bool¶
Reject XML-DSig signatures that carry a
<ds:Object>(signature-wrapping hardening, SAML erratum E91). On by default.
- pygamlastan.security.validate_response(response, config, received_url, expected_idp_entity_id, sp_entity_id, acs_url, expected_request_id=None, client_address=None, relay_state=None, response_signature_verified=None, verified_signed_ids=None, current_proxy_depth=0, now=None, replay_cache=None, persistent_id_store=None, unsafe_no_replay_cache=False, unsafe_no_persistent_id_store=False) ValidationResult¶
Run the full validation suite over a parsed
pygamlastan.core.Responseand return a structuredValidationResult(does not raise on a validation failure).replay_cacheis required by default and may be anInMemoryReplayCacheor any object implementing the replay-cache protocol. If persistent NameID uniqueness is enabled and the response carries a persistent NameID,persistent_id_storeis also required unlessunsafe_no_persistent_id_store=Trueis explicit.
- class pygamlastan.security.ValidationResult¶
-
- checks: list[ValidationCheck]¶
- failures() list[ValidationCheck]¶
- class pygamlastan.security.ValidationCheck¶
One numbered check from the suite.
Replay cache¶
- class pygamlastan.security.InMemoryReplayCache¶
A single-process replay cache.
- check_and_insert(id: str, expiry: datetime.datetime) bool¶
Return
Trueifidis new (now recorded),Falseif it was already seen and not yet expired (a replay).Note
A recorded entry counts as a replay only while
expiryis in the future relative to the wall clock at call time; the cache uses its ownnowand does not honour a caller-supplied clock. Pass anexpiryderived from real time (e.g. the assertion’sNotOnOrAfter), not a fixed test constant.
Note
For multi-worker deployments, pass any object implementing
check_and_insert(id, expiry) -> bool and cleanup() (for example a
Redis-backed cache) wherever a replay_cache is accepted. gamlastan calls
into it and fails closed if a call raises. See
Validation and replay protection.