feat: add SAML SSO authentication for S/4HANA Public Cloud#97
feat: add SAML SSO authentication for S/4HANA Public Cloud#97oisee merged 1 commit intooisee:mainfrom
Conversation
Add programmatic SAML SSO (--saml-auth), fix browser-auth for SAML/IAS, and add --credential-cmd for external credential providers. - 4-step SAML dance: SAP SP → IAS login → SAMLResponse → SAP ACS - SP-initiated (HTTP-POST binding) and IdP-initiated flows - 401 re-auth with stampede protection (mutex + cooldown) - credential-cmd: argv-based exec, JSON output, no shell - HTTPS downgrade prevention at 5 enforcement points - Host validation prevents credential/assertion exfiltration - Credential zeroing after each use - New dep: golang.org/x/net (HTML form parsing) Co-Authored-By: Porfiry
|
Thanks for the thorough review @oisee! And no worries about the mode-default flag — glad it got sorted. Live smoke test resultsWe tested all three scenarios against a live S/4HANA Public Cloud tenant (SAP IAS IdP): 1.
|
| Scenario | Result |
|---|---|
| Wrong password | SAML authentication failed: IAS returned HTTP 401 — no credential leak in output |
| Cross-host form action | form action host "evil.com" does not match SAP host — rejected at enforcement point |
| HTTPS→HTTP downgrade | refusing HTTPS→HTTP downgrade in SAML redirect — blocked |
All three enforcement points work as expected on the live system.
Addressing non-blocking notes
All four are valid observations. We'll submit a follow-up PR:
-
ParseCredentialCmd/strings.Fields— Will add a note to--credential-cmdhelp text about the spaces limitation and recommend wrapper scripts. -
string(password)immutable copy — Acknowledged as a Go language limitation. The byte slices are zeroed, but theurl.Values.Set()string copy persists until GC. Will add an explicit comment documenting this boundary. -
SaveCookiesToFilesecret-bearing — Will add a verbose-mode warning when writing the cookie file, reminding users it contains session secrets. -
Reauth mutex + context timeout — Will add
context.WithTimeout(30s) on the reauth path so concurrent 401 handlers don't block indefinitely. This is the most impactful fix.
Follow-up PR incoming shortly. Thanks again for the careful review!
1. credential-cmd help: note spaces limitation, recommend wrapper scripts 2. saml_auth.go: document string(password) Go immutability limitation 3. browser_auth.go: document cookie file as secret-bearing in SaveCookiesToFile 4. main.go: warn users that saved cookie files contain session secrets 5. http.go: add 30s context timeout on reauth path to prevent indefinite mutex hold during slow/unresponsive IdP SAML dance Addresses all 4 non-blocking notes from oisee's review on PR oisee#97. Co-Authored-By: Porfiry
Summary
Add SAML SSO authentication support for SAP S/4HANA Public Cloud systems where Basic Auth is disabled for business users.
Three new capabilities:
--browser-authfix: Existing browser-based auth now works with SAML/IAS SSO flows. Improved cookie URL filtering (cookieURLsForSAP()queries 4 URL paths), smarter poll timing (500ms intervals with elapsed tracking), and verbose SAML redirect logging.--saml-auth(new): Programmatic SAML SSO without a browser. Performs the full SAP→IAS→SAP SAML dance via HTTP client. Supports SP-initiated (HTTP-POST binding) and IdP-initiated flows. Automatic 401 re-auth with stampede protection (mutex + cooldown). Ideal for CI/CD pipelines. Does not support MFA — use--browser-authfor MFA-protected systems.--credential-cmd(new): External credential provider integration (git-credential-helper pattern). Executes an external command that returns{"username": "...", "password": "..."}JSON. Works with any credential manager (KeePass CLI, 1Password, HashiCorp Vault, etc.). Argv-based execution — no shell interpretation.Security hardening:
canonicalHost)[]byte) after each use;CredentialProvidercallback re-reads on each auth attempt--credential-cmd(argv-basedexec.Command)cmd.Context()propagation for proper Ctrl+C cancellationNew dependency:
golang.org/x/net(forhtmlpackage — robust HTML form parsing instead of regex)Usage examples
Test plan
go test ./pkg/adt/...— all tests passgo build ./cmd/vsp— compiles clean