Hub healthy IdP healthy 1 audit warning Refresh

Governed administration

PingFederate Admin Agent

Write disabled

LAB READY

Configuration work is driven through Codex and the PingFederate agent. The lab is operational for guided demos, with persistence and OIDC runtime still to complete.

80readiness score
Read-only readyVisual onlyApproval required
SLO signed metadataSP cert mounted, Redirect Binding signature required.
NameID correctionLogout uses the ACS NameID, not user1@example.test.
Invalid InResponseToLogoutResponse omits InResponseTo for unsolicited PF SLO response.
OIDC isolationOIDC A/B use dedicated policies and JWT token managers.

Enterprise Readiness

Pilot path
Airbus demopilot ready with constraints
Multi-companyrequires tenancy persistence and connector profiles
Next gapImplement OIDC runtime callbacks and token timer visualization.

Errors & Solutions

2 solved
Invalid InResponseToResolved by omitting InResponseTo on LogoutResponse sent after PF unsolicited SLO.resolved
Missing SessionIndexSP Logout is blocked until ACS captured NameID and SessionIndex.resolved

Missing Prerequisites

Open
PF log mountLog agent exists; mount real PingFederate Hub/IdP folders read-only from the Mint Docker host.open
OIDC callback runtimeAuthorization Code callback and token timers still need implementation.open
Persistent event storePostgreSQL required before long retention/export.open

Configuration Audit

Audit JSONOpen map
SAML SSO A/B SAML applications are configured in IAM Lab. SP metadata and ACS endpoints are generated from config. ready
Signed SAML SLO SAML clients expose SLO URLs. SP initiated LogoutRequest is signed with rsa-sha256. ready
IdP sessions per adapter HTML Form adapter is the expected IdP session boundary. Hub session state remains disabled by design. ready
Dedicated OIDC governance OIDC A/B have separate client ids. OIDC A/B plans use dedicated JWT access token managers. configured
PingFederate log agent pf-log-agent-scan and pf-log-agent-follow are available. Logs are redacted before being posted to IAM Lab runs. available
Read-only PF audit Audit JSON is available without secrets. Expected objects are derived from IAM Lab configuration. available
Governed write path Write remains disabled by default. Execution requires explicit approval phrase. guarded
Enterprise retention and export Current run state is in-memory. Long retention, export, and multi-tenant separation are not complete. gap

Execution strategy

Strategy JSONPrepare JSON
intake Capture Luc's exact request and target
classify Classify operation, risk and blast radius
inventory Read current PingFederate state
snapshot Save pre-change state outside Git
schema_validation Validate endpoint and payload shape
diff Show expected before/after change
approval Require explicit approval phrase
execute Run a single write operation
verify Read back PingFederate state and test behavior
report Write an EngineeringReport with evidence

Phase 2 · hub

create_or_update_saml_sp_connection

lab-pf-saml-sp-iamlab-saml-a-local

dry_run
{
  "phase": "2",
  "mode": "dry_run",
  "target": "hub",
  "status": "draft_payload_requires_pingfederate_schema_validation",
  "operation": "create_or_update_saml_sp_connection",
  "name": "lab-pf-saml-sp-iamlab-saml-a-local",
  "application": {
    "id": "saml-a",
    "display_name": "SAML Inspector A",
    "protocol": "SAML",
    "mode": "saml-sp",
    "base_url": "https://saml-a.sabathe.eu",
    "enabled": true
  },
  "admin_api_base": "https://hub-adm.sabathe.eu/pf-admin-api/v1",
  "expected_sp_metadata": {
    "entity_id": "http://127.0.0.1:18102/apps/saml-a/metadata/local",
    "metadata_url": "http://127.0.0.1:18102/apps/saml-a/metadata/local",
    "acs_url": "http://127.0.0.1:18102/saml/acs",
    "slo_url": "http://127.0.0.1:18102/saml/slo"
  },
  "draft_payload": {
    "connection_name": "lab-pf-saml-sp-iamlab-saml-a-local",
    "entity_id": "http://127.0.0.1:18102/apps/saml-a/metadata/local",
    "base_url": "https://saml-a.sabathe.eu",
    "acs_urls": [
      "http://127.0.0.1:18102/saml/acs"
    ],
    "slo_url": "http://127.0.0.1:18102/saml/slo",
    "metadata_url": "http://127.0.0.1:18102/apps/saml-a/metadata/local",
    "signing": {
      "authn_requests_signed": false,
      "want_assertions_signed": true,
      "certificate_source": "PingFederate key pair to select manually in phase 2"
    },
    "activation": "manual_approval_required"
  },
  "checks_before_write": [
    "Confirm target PingFederate is Hub",
    "Snapshot existing SP connections",
    "Confirm signing certificate/key pair",
    "Validate metadata URL or import XML",
    "Show payload and request explicit approval"
  ]
}

Phase 3 · hub

create_or_update_oidc_client

lab-pf-oidc-client-iamlab-oidc-a-configured

dry_run
{
  "phase": "3",
  "mode": "dry_run",
  "target": "hub",
  "status": "draft_payload_requires_pingfederate_schema_validation",
  "operation": "create_or_update_oidc_client",
  "name": "lab-pf-oidc-client-iamlab-oidc-a-configured",
  "application": {
    "id": "oidc-a",
    "display_name": "OIDC Inspector A",
    "protocol": "OIDC",
    "mode": "oidc-client",
    "base_url": "https://oidc-a.sabathe.eu",
    "enabled": true
  },
  "admin_api_base": "https://hub-adm.sabathe.eu/pf-admin-api/v1",
  "expected_oidc_client": {
    "client_id": "oidc-a",
    "client_secret_env": "OIDC_A_CLIENT_SECRET",
    "redirect_uri": "https://oidc-a.sabathe.eu/callback",
    "post_logout_redirect_uri": "https://oidc-a.sabathe.eu/logout/callback",
    "scopes": [
      "openid",
      "profile",
      "email"
    ]
  },
  "draft_payload": {
    "client_id": "oidc-a",
    "name": "lab-pf-oidc-client-iamlab-oidc-a-configured",
    "redirect_uris": [
      "https://oidc-a.sabathe.eu/callback"
    ],
    "post_logout_redirect_uris": [
      "https://oidc-a.sabathe.eu/logout/callback"
    ],
    "grant_types": [
      "authorization_code"
    ],
    "response_types": [
      "code"
    ],
    "scopes": [
      "openid",
      "profile",
      "email"
    ],
    "client_secret": "[REDACTED]",
    "activation": "manual_approval_required"
  },
  "checks_before_write": [
    "Confirm target PingFederate is Hub",
    "Snapshot existing OAuth clients",
    "Confirm redirect URI reachability",
    "Confirm client secret generation/storage mode",
    "Show payload and request explicit approval"
  ]
}

Phase 4 · hub_and_idp

create_or_update_hub_idp_federation_link

lab-pf-federation-link-hub-idp-local

dry_run
{
  "phase": "4",
  "mode": "dry_run",
  "target": "hub_and_idp",
  "status": "draft_payload_requires_pingfederate_schema_validation",
  "operation": "create_or_update_hub_idp_federation_link",
  "name": "lab-pf-federation-link-hub-idp-local",
  "admin_api_bases": {
    "hub": "https://hub-adm.sabathe.eu/pf-admin-api/v1",
    "idp": "https://idp-adm.sabathe.eu/pf-admin-api/v1"
  },
  "runtime_urls": {
    "hub": "https://hub.sabathe.eu",
    "idp": "https://idp.sabathe.eu"
  },
  "draft_payload": {
    "hub_side": {
      "object_type": "sp_idp_connection",
      "connection_name": "lab-pf-sp-idpconn-hub-to-idp-local",
      "expected_endpoint_family": "sp/idpConnections",
      "partner_entity": "idp.sabathe.eu",
      "metadata_source": "idp_runtime_metadata_or_admin_export",
      "activation": "manual_approval_required"
    },
    "idp_side": {
      "object_type": "idp_sp_connection",
      "connection_name": "lab-pf-idp-spconn-idp-to-hub-local",
      "expected_endpoint_family": "idp/spConnections",
      "partner_entity": "hub.sabathe.eu",
      "metadata_source": "hub_runtime_metadata_or_admin_export",
      "activation": "manual_approval_required"
    },
    "policy_attachment": {
      "source": "html_form_adapter_with_simple_pcv",
      "status": "planned"
    }
  },
  "checks_before_write": [
    "Inventory Hub SP IdP connections and IdP SP connections",
    "Confirm federation direction and entity IDs",
    "Validate public certificates and signing expectations",
    "Show Hub-side and IdP-side payloads",
    "Request explicit approval for each side"
  ]
}

Phase 5 · idp

create_or_update_html_form_adapter_with_simple_pcv

lab-pf-html-form-pcv-idp-local

dry_run
{
  "phase": "5",
  "mode": "dry_run",
  "target": "idp",
  "status": "draft_payload_requires_pingfederate_schema_validation",
  "operation": "create_or_update_html_form_adapter_with_simple_pcv",
  "name": "lab-pf-html-form-pcv-idp-local",
  "admin_api_base": "https://idp-adm.sabathe.eu/pf-admin-api/v1",
  "draft_payload": {
    "password_credential_validator": {
      "id": "lab-simple-pcv",
      "type": "simple_pcv",
      "credential_source": "manual_lab_only",
      "secret_policy": "no_password_in_git_or_cli_output",
      "activation": "manual_approval_required"
    },
    "html_form_adapter": {
      "id": "lab-html-form",
      "name": "Lab HTML Form Adapter",
      "pcv_reference": "lab-simple-pcv",
      "session_state": "lab_default",
      "activation": "manual_approval_required"
    },
    "policy_contract": {
      "status": "planned",
      "attributes": [
        "subject",
        "email"
      ]
    }
  },
  "checks_before_write": [
    "Confirm target engine for the login form",
    "Snapshot existing adapters and PCVs",
    "Confirm lab-only user source and password handling",
    "Show PCV and HTML Form payloads",
    "Request explicit approval before any write"
  ]
}

Phase 7 · hub_and_idp

bootstrap_lab_saml_federation

lab-pf-bootstrap-saml-saml-a-local

dry_run
{
  "phase": "7",
  "mode": "dry_run",
  "target": "hub_and_idp",
  "status": "manual_approval_required",
  "operation": "bootstrap_lab_saml_federation",
  "name": "lab-pf-bootstrap-saml-saml-a-local",
  "admin_api_bases": {
    "hub": "https://hub-adm.sabathe.eu/pf-admin-api/v1",
    "idp": "https://idp-adm.sabathe.eu/pf-admin-api/v1"
  },
  "principle": "Create the smallest lab federation path: local password user -> HTML Form -> policy contract -> Hub/IdP federation -> SAML SP connection.",
  "lab_user": {
    "username": "user1",
    "password_env": "PF_LAB_USER1_PASSWORD",
    "password_value": "not_exported"
  },
  "objects": [
    {
      "order": 1,
      "target": "idp",
      "operation": "create_simple_password_pcv",
      "name": "lab-simple-pcv",
      "endpoint_family": "passwordCredentialValidators",
      "payload_ref": "draft_payload.password_credential_validator",
      "secret_source": "PF_LAB_USER1_PASSWORD",
      "desired_state": {
        "users": [
          {
            "username": "user1",
            "password": "[REDACTED]"
          }
        ]
      }
    },
    {
      "order": 2,
      "target": "idp",
      "operation": "create_html_form_adapter",
      "name": "lab-html-form",
      "endpoint_family": "idp/adapters",
      "payload_ref": "draft_payload.html_form_adapter",
      "depends_on": [
        "lab-simple-pcv"
      ]
    },
    {
      "order": 3,
      "target": "idp",
      "operation": "create_authentication_policy_contract",
      "name": "lab-policy-contract-basic",
      "endpoint_family": "authenticationPolicyContracts",
      "desired_state": {
        "extended_attributes": [
          "subject",
          "email"
        ],
        "core_attribute": "subject"
      }
    },
    {
      "order": 4,
      "target": "idp",
      "operation": "create_authentication_policy",
      "name": "lab-policy-html-form-basic",
      "endpoint_family": "authenticationPolicies",
      "desired_state": {
        "root": "lab-html-form",
        "success": "lab-policy-contract-basic",
        "flow": "HTML Form directly fulfills the policy contract"
      },
      "depends_on": [
        "lab-html-form",
        "lab-policy-contract-basic"
      ]
    },
    {
      "order": 5,
      "target": "hub_and_idp",
      "operation": "create_hub_idp_federation_link",
      "name": "lab-pf-federation-link-hub-idp-local",
      "payload_ref": "hub_idp_link_plan",
      "depends_on": [
        "lab-policy-html-form-basic"
      ]
    },
    {
      "order": 6,
      "target": "hub",
      "operation": "create_saml_sp_connection",
      "name": "lab-pf-saml-sp-iamlab-saml-a-local",
      "payload_ref": "saml_sp_connection_plan",
      "depends_on": [
        "lab-pf-federation-link-hub-idp-local"
      ]
    },
    {
      "order": 7,
      "target": "hub",
      "operation": "add_policy_contract_mapping_to_saml_connection",
      "name": "lab-saml-a-policy-contract-mapping",
      "endpoint_family": "idp/spConnections",
      "desired_state": {
        "connection": "lab-pf-saml-sp-iamlab-saml-a-local",
        "policy_contract": "lab-policy-contract-basic",
        "mapping": {
          "subject": "adapter_or_contract.subject",
          "email": "adapter_or_contract.email"
        }
      },
      "depends_on": [
        "lab-pf-saml-sp-iamlab-saml-a-local",
        "lab-policy-contract-basic"
      ]
    }
  ],
  "included_plans": {
    "html_form_pcv": {
      "phase": "5",
      "mode": "dry_run",
      "target": "idp",
      "status": "draft_payload_requires_pingfederate_schema_validation",
      "operation": "create_or_update_html_form_adapter_with_simple_pcv",
      "name": "lab-pf-html-form-pcv-idp-local",
      "admin_api_base": "https://idp-adm.sabathe.eu/pf-admin-api/v1",
      "draft_payload": {
        "password_credential_validator": {
          "id": "lab-simple-pcv",
          "type": "simple_pcv",
          "credential_source": "manual_lab_only",
          "secret_policy": "no_password_in_git_or_cli_output",
          "activation": "manual_approval_required"
        },
        "html_form_adapter": {
          "id": "lab-html-form",
          "name": "Lab HTML Form Adapter",
          "pcv_reference": "lab-simple-pcv",
          "session_state": "lab_default",
          "activation": "manual_approval_required"
        },
        "policy_contract": {
          "status": "planned",
          "attributes": [
            "subject",
            "email"
          ]
        }
      },
      "checks_before_write": [
        "Confirm target engine for the login form",
        "Snapshot existing adapters and PCVs",
        "Confirm lab-only user source and password handling",
        "Show PCV and HTML Form payloads",
        "Request explicit approval before any write"
      ]
    },
    "hub_idp_link": {
      "phase": "4",
      "mode": "dry_run",
      "target": "hub_and_idp",
      "status": "draft_payload_requires_pingfederate_schema_validation",
      "operation": "create_or_update_hub_idp_federation_link",
      "name": "lab-pf-federation-link-hub-idp-local",
      "admin_api_bases": {
        "hub": "https://hub-adm.sabathe.eu/pf-admin-api/v1",
        "idp": "https://idp-adm.sabathe.eu/pf-admin-api/v1"
      },
      "runtime_urls": {
        "hub": "https://hub.sabathe.eu",
        "idp": "https://idp.sabathe.eu"
      },
      "draft_payload": {
        "hub_side": {
          "object_type": "sp_idp_connection",
          "connection_name": "lab-pf-sp-idpconn-hub-to-idp-local",
          "expected_endpoint_family": "sp/idpConnections",
          "partner_entity": "idp.sabathe.eu",
          "metadata_source": "idp_runtime_metadata_or_admin_export",
          "activation": "manual_approval_required"
        },
        "idp_side": {
          "object_type": "idp_sp_connection",
          "connection_name": "lab-pf-idp-spconn-idp-to-hub-local",
          "expected_endpoint_family": "idp/spConnections",
          "partner_entity": "hub.sabathe.eu",
          "metadata_source": "hub_runtime_metadata_or_admin_export",
          "activation": "manual_approval_required"
        },
        "policy_attachment": {
          "source": "html_form_adapter_with_simple_pcv",
          "status": "planned"
        }
      },
      "checks_before_write": [
        "Inventory Hub SP IdP connections and IdP SP connections",
        "Confirm federation direction and entity IDs",
        "Validate public certificates and signing expectations",
        "Show Hub-side and IdP-side payloads",
        "Request explicit approval for each side"
      ]
    },
    "saml_sp_connection": {
      "phase": "2",
      "mode": "dry_run",
      "target": "hub",
      "status": "draft_payload_requires_pingfederate_schema_validation",
      "operation": "create_or_update_saml_sp_connection",
      "name": "lab-pf-saml-sp-iamlab-saml-a-local",
      "application": {
        "id": "saml-a",
        "display_name": "SAML Inspector A",
        "protocol": "SAML",
        "mode": "saml-sp",
        "base_url": "https://saml-a.sabathe.eu",
        "enabled": true
      },
      "admin_api_base": "https://hub-adm.sabathe.eu/pf-admin-api/v1",
      "expected_sp_metadata": {
        "entity_id": "http://127.0.0.1:18102/apps/saml-a/metadata/local",
        "metadata_url": "http://127.0.0.1:18102/apps/saml-a/metadata/local",
        "acs_url": "http://127.0.0.1:18102/saml/acs",
        "slo_url": "http://127.0.0.1:18102/saml/slo"
      },
      "draft_payload": {
        "connection_name": "lab-pf-saml-sp-iamlab-saml-a-local",
        "entity_id": "http://127.0.0.1:18102/apps/saml-a/metadata/local",
        "base_url": "https://saml-a.sabathe.eu",
        "acs_urls": [
          "http://127.0.0.1:18102/saml/acs"
        ],
        "slo_url": "http://127.0.0.1:18102/saml/slo",
        "metadata_url": "http://127.0.0.1:18102/apps/saml-a/metadata/local",
        "signing": {
          "authn_requests_signed": false,
          "want_assertions_signed": true,
          "certificate_source": "PingFederate key pair to select manually in phase 2"
        },
        "activation": "manual_approval_required"
      },
      "checks_before_write": [
        "Confirm target PingFederate is Hub",
        "Snapshot existing SP connections",
        "Confirm signing certificate/key pair",
        "Validate metadata URL or import XML",
        "Show payload and request explicit approval"
      ]
    }
  },
  "checks_before_write": [
    "Capture Hub and IdP inventory snapshots",
    "Validate exact PingFederate Admin API schemas for every object type",
    "Confirm Simple Password PCV is available in this PingFederate version",
    "Load PF_LAB_USER1_PASSWORD from .env.local only",
    "Create objects disabled where PingFederate supports disabled creation",
    "Show full diff for each object",
    "Request explicit approval for the whole bundle and execute one object at a time"
  ]
}

Phase 8 · hub_and_idp

enable_saml_logout_and_adapter_session_tracking

lab-pf-saml-logout-readiness-no-mfa

dry_run
{
  "phase": "8",
  "mode": "dry_run",
  "target": "hub_and_idp",
  "status": "manual_approval_required",
  "operation": "enable_saml_logout_and_adapter_session_tracking",
  "name": "lab-pf-saml-logout-readiness-no-mfa",
  "admin_api_bases": {
    "hub": "https://hub-adm.sabathe.eu/pf-admin-api/v1",
    "idp": "https://idp-adm.sabathe.eu/pf-admin-api/v1"
  },
  "applications": [
    {
      "id": "saml-a",
      "display_name": "SAML Inspector A",
      "protocol": "SAML",
      "mode": "saml-sp",
      "base_url": "https://saml-a.sabathe.eu",
      "enabled": true
    },
    {
      "id": "saml-b",
      "display_name": "SAML Inspector B",
      "protocol": "SAML",
      "mode": "saml-sp",
      "base_url": "https://saml-b.sabathe.eu",
      "enabled": true
    }
  ],
  "desired_state": {
    "hub_saml_app_connections": [
      {
        "connection_id": "labsamlasp",
        "enabled_profiles": [
          "SP_INITIATED_SSO",
          "IDP_INITIATED_SSO",
          "IDP_INITIATED_SLO",
          "SP_INITIATED_SLO"
        ],
        "slo_service_endpoints": [
          {
            "binding": "REDIRECT",
            "url": "https://saml-a.sabathe.eu/saml/slo"
          },
          {
            "binding": "POST",
            "url": "https://saml-a.sabathe.eu/saml/slo"
          }
        ]
      },
      {
        "connection_id": "labsamlbsp",
        "enabled_profiles": [
          "SP_INITIATED_SSO",
          "IDP_INITIATED_SSO",
          "IDP_INITIATED_SLO",
          "SP_INITIATED_SLO"
        ],
        "slo_service_endpoints": [
          {
            "binding": "REDIRECT",
            "url": "https://saml-b.sabathe.eu/saml/slo"
          },
          {
            "binding": "POST",
            "url": "https://saml-b.sabathe.eu/saml/slo"
          }
        ]
      }
    ],
    "hub_to_idp_connection": {
      "connection_id": "labidpconnidpnomfa",
      "enabled_profiles": [
        "SP_INITIATED_SSO",
        "IDP_INITIATED_SSO",
        "IDP_INITIATED_SLO",
        "SP_INITIATED_SLO"
      ],
      "idp_slo_endpoint": "https://idp.sabathe.eu/idp/SLO.saml2"
    },
    "idp_to_hub_connection": {
      "connection_id": "labspconnhubnomfa",
      "enabled_profiles": [
        "SP_INITIATED_SSO",
        "IDP_INITIATED_SSO",
        "IDP_INITIATED_SLO",
        "SP_INITIATED_SLO"
      ],
      "hub_slo_endpoint": "https://hub.sabathe.eu/sp/SLO.saml2"
    },
    "idp_session_settings": {
      "endpoint": "session/settings",
      "trackAdapterSessionsForLogout": true,
      "revokeUserSessionOnLogout": true,
      "scope": "global PingFederate setting; use only after snapshot/diff"
    },
    "html_form_adapter": {
      "id": "labhtmlform",
      "session_state": "Per Adapter",
      "session_policy": "IdP HTML Form adapter keeps its own adapter-scoped session; no Hub session settings are changed."
    }
  },
  "checks_before_write": [
    "Snapshot Hub idp/spConnections for saml-a and saml-b",
    "Snapshot Hub sp/idpConnections/labidpconnidpnomfa",
    "Snapshot IdP idp/spConnections/labspconnhubnomfa",
    "Snapshot IdP idp/adapters/labhtmlform and session/settings",
    "Diff enabledProfiles and sloServiceEndpoints before PUT",
    "Confirm global IdP session tracking impact with Luc",
    "Apply one object at a time and verify SAML login then logout from Chrome"
  ]
}

Instance Log View

Agent available
hub-runtime  mount Hub runtime logs read-only from Mint Docker host
hub-admin    Admin API actions are visible through governed reports
idp-runtime  mount IdP runtime logs read-only from Mint Docker host
idp-admin    Session State = Per Adapter observed in current lab
Data refreshed from IAM-Lab runtimeStreaming liveAuto refreshManual