Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

openhound-saml-producer

This library builds the SAML graph nodes and edges for OpenHound extensions. It is a prototype. It is published on PyPI as openhound-saml-producer. See Release steps.

Two extensions that see the same SAML endpoint write the same node. For example, an issuer or an assertion consumer service (ACS) route gets the same ID in every extension. The ACS is the URL where a service provider receives SAML assertions. Each extension writes its own environment ID on that node as environmentid. The correlator later decides the owner's environment.

What it does

  • Builds owned nodes for identity providers, service providers, and claim mappings. Their IDs come from the producer name, the environment, and the native key.
  • Builds shared nodes for issuers and ACS routes. Their IDs come from the route strings only. Each shared-node builder takes the producer's environment ID, which it writes as environmentid.
  • Builds account resolution rules and fields (v0.3). A producer gives typed conditions (AccountResolutionCondition). The library writes the rule text from the profile templates, so a producer never writes rule text.
  • Rejects extra properties that do not start with the producer prefix.
  • Builds v0.4 set grants (SetPolicyFact, set_grant_edges), claim projections, eligibility exceptions (EligibilityExceptionFact, eligibility_exception_edge), and claim value residuals (a ClaimValueFact with a set_policy). A fact carries v0.4.0 only when it uses a v0.4 kind or property. All other output stays v0.3.0.
  • Builds the portable principal set (v0.4), only for a platform that has no group node in the graph. PrincipalSetFact gives a SAML_PrincipalSet node whose ID is the contract's portable set key (principal_set_id). SetMembershipFact gives one SAML_EffectiveMemberOfPrincipalSet edge. A SetPolicyFact with the profile saml_principal_set_membership_v1 grants access from that node. A provider should use the portable profile only when the platform has no group node: assert_conformant returns a warning for a provider that uses both profiles.
  • Declares the v0.4 edges: edge_defs takes set_kinds for set grants and exceptions, and NodeKind.PRINCIPAL_SET declares the membership edges.
  • Writes assertion requirements. A ServiceProviderFact with assertion_requirements (registered profile IDs, for example aws_iam_role_session_name_v1) is a v0.4.1 fact with the property assertion_requirement_profiles. An unknown ID is a FactError.
  • Writes the same relationship context on every edge.

IdP example

This example writes one identity provider, its tenant issuer, and one route.

from openhound_saml_producer import IssuerFact, Producer, RouteFact
from openhound_saml_producer.conventions import entra_external_route
from openhound_saml_producer.facts import FederationProviderFact
from openhound_saml_producer.idp import federation_provider_edges, federation_provider_node
from openhound_saml_producer.shared import acs_node, issuer_node

TENANT = "11111111-2222-3333-4444-555555555555"
PRODUCER = Producer(name="entra_saml", extension="openhound-entra-saml",
                    prefix="az_", technology="entra", source_kind="SAML")

provider = FederationProviderFact(
    environment_id=f"entra-saml-tenant:{TENANT}",
    native_key="22222222-3333-4444-5555-666666666666",
    native_kind="AZServicePrincipal",
    native_object_id="",  # empty: the native key is shown
    name="Example app",
    enabled=True,
    extras={"az_tenant_id": TENANT},
)
issuer = IssuerFact(entity_id=f"https://sts.windows.net/{TENANT}/")
route: RouteFact = entra_external_route(TENANT)

nodes = [
    federation_provider_node(PRODUCER, provider),
    issuer_node(PRODUCER, provider.environment_id, issuer),
    acs_node(PRODUCER, provider.environment_id, route),
]
edges, warnings = federation_provider_edges(
    PRODUCER, provider, native=None, issuer=issuer,
    routes=[route], claim_mapping_keys=[],
)

warnings holds BuildWarning values. The extension logs them. They are not graph output.

SP example

This example writes one service provider and its trust of the same issuer.

from openhound_saml_producer.facts import ServiceProviderFact
from openhound_saml_producer.sp import service_provider_edges, service_provider_node

sp = ServiceProviderFact(
    environment_id=f"entra-saml-tenant:{TENANT}",
    native_key="sp-native-key",
    native_kind="ExternalFederation",
    native_object_id="",
    name="Example trust",
    enabled=True,
)
sp_node = service_provider_node(PRODUCER, sp)
sp_edges, sp_warnings = service_provider_edges(
    PRODUCER, sp, native=None, trusted_issuer=issuer, routes=[route],
)

The edge ends for issuer and route use the same IDs as the shared nodes above. You do not compute those IDs yourself.

Limits

  • Node and edge IDs use the rules in the shared normalization design. Do not change them without a contract review.
  • The library writes no timestamp on nodes. BloodHound adds its own.
  • The checks in openhound_saml_producer.testing.conformance run on whole payloads. assert_conformant checks one payload. assert_shared_nodes_agree checks that two producers' copies of one shared node match, except for environmentid. Use them in tests. assert_conformant also checks the contract and relationship-context versions on every edge, rejects unprefixed extra edge properties, requires each SAML_* node to carry exactly its own kind and SAML, and applies the correlator's account-evidence rules to SAML_EligibleFor and SAML_HasAccount edges. Each fact must carry v0.4.1 if it lists assertion requirements, v0.4.0 if it has other v0.4 content, and v0.3.0 if it has none. The v0.4 rules agree with the correlator. A passing check returns a list of warnings. One warning is for a provider that has a complete set grant and no expanded facts: stop expanded facts only after the rollout gate (design section 14.5) passes.

Release steps

A GitHub Release publishes the package to PyPI. Publication has these steps.

  1. Set version in pyproject.toml, for example 0.4.6rc1. Merge the change to dev-jim for a release candidate, or to main for a stable version.
  2. In GitHub, create a Release. Set the tag to saml-producer-v<version>, for example saml-producer-v0.4.6rc1.
  3. Set the target branch. Use dev-jim for a release candidate and main for a stable version.
  4. Set the prerelease flag. Set it for a release candidate (a, b, or rc version). Clear it for a stable version.
  5. Publish the Release. The workflow release-saml-producer.yml builds the files. It checks the version and the branch. It stops if a check fails.
  6. Approve the pypi environment deployment in GitHub Actions. PyPI gets the files only after this approval.

Metadata

Release files for openhound-saml-producer 0.4.6rc1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for openhound-saml-producer 0.4.6rc1
File Size Uploaded Provenance Actions
openhound_saml_producer-0.4.6rc1.tar.gz 73.9 kB Without provenance Details for openhound_saml_producer-0.4.6rc1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for openhound-saml-producer 0.4.6rc1
File Interpreter ABI Platform Actions
openhound_saml_producer-0.4.6rc1-py3-none-any.whl Python 3 none any Details for openhound_saml_producer-0.4.6rc1-py3-none-any.whl

Total release size: 141.1 kB

Release files / openhound_saml_producer-0.4.6rc1.tar.gz

Download URL openhound_saml_producer-0.4.6rc1.tar.gz
Size 73.9 kB
Tags Source
SHA-256 checksum
How to use checksums
a7abbae3aeda1a346dc9a9ba7e8ad139b61b085df85394bfca512362cdb98e3d
BLAKE2b-256 checksum
How to use checksums
64b7ef71d434945f885ebbf0383f9f288ab4067be51f04c0f40ffea00ec33cf8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.8 {"installer":{"name":"uv","version":"0.13.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / openhound_saml_producer-0.4.6rc1-py3-none-any.whl

Download URL openhound_saml_producer-0.4.6rc1-py3-none-any.whl
Size 67.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2b3be340d9d34b773fd22244bcc2088e3be074001ef0f760ee9a963e1fad108c
BLAKE2b-256 checksum
How to use checksums
c2d29b15c0e36f8f2d0bd6f1e59c9fa33a04ed38b6e6498b315305f0ba44610d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.8 {"installer":{"name":"uv","version":"0.13.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for openhound-saml-producer 0.4.6rc1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page