{"id":16540873,"url":"https://github.com/itzg/saml-auth-proxy","last_synced_at":"2025-09-04T05:33:17.212Z","repository":{"id":36254712,"uuid":"171171378","full_name":"itzg/saml-auth-proxy","owner":"itzg","description":"Provides a SAML SP authentication proxy for backend web services","archived":false,"fork":false,"pushed_at":"2025-07-31T01:21:16.000Z","size":145,"stargazers_count":72,"open_issues_count":12,"forks_count":22,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-07-31T04:05:57.927Z","etag":null,"topics":["proxy-server","saml"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/itzg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"custom":["https://www.buymeacoffee.com/itzg","https://paypal.me/itzg"]}},"created_at":"2019-02-17T20:54:35.000Z","updated_at":"2025-07-31T01:20:20.000Z","dependencies_parsed_at":"2023-02-14T14:01:56.071Z","dependency_job_id":"964ec1af-e7b7-4074-805b-3a9477696959","html_url":"https://github.com/itzg/saml-auth-proxy","commit_stats":{"total_commits":87,"total_committers":9,"mean_commits":9.666666666666666,"dds":0.3908045977011494,"last_synced_commit":"e1140121e1ca51ff7e4d02359d6fc1e57dee70bf"},"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"purl":"pkg:github/itzg/saml-auth-proxy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzg%2Fsaml-auth-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzg%2Fsaml-auth-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzg%2Fsaml-auth-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzg%2Fsaml-auth-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/itzg","download_url":"https://codeload.github.com/itzg/saml-auth-proxy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzg%2Fsaml-auth-proxy/sbom","scorecard":{"id":497746,"data":{"date":"2025-08-11","repo":{"name":"github.com/itzg/saml-auth-proxy","commit":"ec738fa43b1df09b3d9c4018bcce7c711d2cf110"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.8,"checks":[{"name":"Code-Review","score":6,"reason":"Found 11/18 approved changesets -- score normalized to 6","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":9,"reason":"10 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 9","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/release.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: MIT License: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/itzg/saml-auth-proxy/release.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/itzg/saml-auth-proxy/test.yml/master?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:1","Warn: containerImage not pinned by hash: Dockerfile:8: pin your Docker image by updating alpine to alpine@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1","Warn: containerImage not pinned by hash: Dockerfile.release:1: pin your Docker image by updating alpine:3.9 to alpine:3.9@sha256:414e0518bb9228d35e4cd5165567fb91d26c6a214e9c95899e1e056fcd349011","Info:   0 out of   2 third-party GitHubAction dependencies pinned","Info:   0 out of   3 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact 1.17.3 not signed: https://api.github.com/repos/itzg/saml-auth-proxy/releases/236436881","Warn: release artifact 1.17.2 not signed: https://api.github.com/repos/itzg/saml-auth-proxy/releases/229466635","Warn: release artifact 1.17.1 not signed: https://api.github.com/repos/itzg/saml-auth-proxy/releases/228894516","Warn: release artifact 1.17.0 not signed: https://api.github.com/repos/itzg/saml-auth-proxy/releases/228872300","Warn: release artifact 1.16.1 not signed: https://api.github.com/repos/itzg/saml-auth-proxy/releases/225840133","Warn: release artifact 1.17.3 does not have provenance: https://api.github.com/repos/itzg/saml-auth-proxy/releases/236436881","Warn: release artifact 1.17.2 does not have provenance: https://api.github.com/repos/itzg/saml-auth-proxy/releases/229466635","Warn: release artifact 1.17.1 does not have provenance: https://api.github.com/repos/itzg/saml-auth-proxy/releases/228894516","Warn: release artifact 1.17.0 does not have provenance: https://api.github.com/repos/itzg/saml-auth-proxy/releases/228872300","Warn: release artifact 1.16.1 does not have provenance: https://api.github.com/repos/itzg/saml-auth-proxy/releases/225840133"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-19T20:55:58.259Z","repository_id":36254712,"created_at":"2025-08-19T20:55:58.259Z","updated_at":"2025-08-19T20:55:58.259Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273555973,"owners_count":25126459,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-04T02:00:08.968Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["proxy-server","saml"],"created_at":"2024-10-11T18:53:30.830Z","updated_at":"2025-09-04T05:33:17.201Z","avatar_url":"https://github.com/itzg.png","language":"Go","funding_links":["https://www.buymeacoffee.com/itzg","https://paypal.me/itzg"],"categories":[],"sub_categories":[],"readme":"[![Test](https://github.com/itzg/saml-auth-proxy/actions/workflows/test.yml/badge.svg)](https://github.com/itzg/saml-auth-proxy/actions/workflows/test.yml)\n[![](https://img.shields.io/github/release/itzg/saml-auth-proxy.svg?style=flat)](https://github.com/itzg/saml-auth-proxy/releases/latest)\n[![](https://img.shields.io/docker/pulls/itzg/saml-auth-proxy.svg?style=flat)](https://hub.docker.com/r/itzg/saml-auth-proxy)\n\nProvides a SAML SP authentication proxy for backend web services\n\n## Usage\n\n```text\n  -allow-idp-initiated\n        If set, allows for IdP initiated authentication flow (env SAML_PROXY_ALLOW_IDP_INITIATED)\n  -attribute-header-mappings attribute=header\n        Comma separated list of attribute=header pairs mapping SAML IdP response attributes to forwarded request header (env SAML_PROXY_ATTRIBUTE_HEADER_MAPPINGS)\n  -attribute-header-wildcard string\n        Maps all SAML attributes with this option as a prefix, slashes in attribute names will be replaced by dashes (env SAML_PROXY_ATTRIBUTE_HEADER_WILDCARD)\n  -auth-verify bool\n        Enables verify path endpoint for forward auth and trusts X-Forwarded headers (env SAML_PROXY_AUTH_VERIFY)\n  -auth-verify-path string\n        Path under BaseUrl that will respond with a 200 when authenticated (env SAML_PROXY_AUTH_VERIFY_PATH) (default \"/_verify\")\n  -authorize-attribute attribute\n        Enables authorization and specifies the attribute to check for authorized values (env SAML_PROXY_AUTHORIZE_ATTRIBUTE)\n  -authorize-values values\n        If enabled, comma separated list of values that must be present in the authorize attribute (env SAML_PROXY_AUTHORIZE_VALUES)\n  -backend-url URL\n        URL of the backend being proxied (env SAML_PROXY_BACKEND_URL)\n  -base-url URL\n        External URL of this proxy (env SAML_PROXY_BASE_URL)\n  -bind host:port\n        host:port to bind for serving HTTP (env SAML_PROXY_BIND) (default \":8080\")\n  -cookie-domain string\n        Overrides the domain set on the session cookie. By default the BaseUrl host is used. (env SAML_PROXY_COOKIE_DOMAIN)\n  -cookie-max-age duration\n        Specifies the amount of time the authentication token will remain valid (env SAML_PROXY_COOKIE_MAX_AGE) (default 2h0m0s) \n  -cookie-name string\n        Name of the cookie that tracks session token (env SAML_PROXY_COOKIE_NAME) (default \"token\")\n  -entity-id string\n        Entity ID of this service provider (env SAML_PROXY_ENTITY_ID)\n  -idp-ca-path path\n        Optional path to a CA certificate PEM file for the IdP (env SAML_PROXY_IDP_CA_PATH)\n  -idp-metadata-url URL\n        URL of the IdP's metadata XML, can be a local file by specifying the file:// scheme (env SAML_PROXY_IDP_METADATA_URL)\n  -initiate-session-path path\n        If set, initiates a SAML authentication flow only when a user visits this path. This will allow anonymous users to access to the backend. (env SAML_PROXY_INITIATE_SESSION_PATH)\n  -name-id-format string\n        One of unspecified, transient, email, or persistent to use a standard format or give a full URN of the name ID format (env SAML_PROXY_NAME_ID_FORMAT) (default \"transient\")\n  -name-id-mapping header\n        Name of the request header to convey the SAML nameID/subject (env SAML_PROXY_NAME_ID_MAPPING)\n  -new-auth-webhook-url URL\n        URL of webhook that will get POST'ed when a new authentication is processed (env SAML_PROXY_NEW_AUTH_WEBHOOK_URL)\n  -sign-requests\n        If set, enables SAML request signing (env SAML_PROXY_SIGN_REQUESTS)\n  -encrypt-jwt\n        If set, JWTs will be encrypted as JWE (env SAML_PROXY_ENCRYPT_JWT)\n  -sp-cert-path path\n        The path to the X509 public certificate PEM file for this SP (env SAML_PROXY_SP_CERT_PATH) (default \"saml-auth-proxy.cert\")\n  -sp-key-path path\n        The path to the X509 private key PEM file for this SP (env SAML_PROXY_SP_KEY_PATH) (default \"saml-auth-proxy.key\")\n  -static-relay-state string\n        A fixed RelayState value, such as a short URL. Will be trimmed to 80 characters to conform with SAML. The default generates random bytes that are Base64\n encoded. (env SAML_PROXY_STATIC_RELAY_STATE)\n  -version\n        show version and exit\n```\n\nThe snake-case values, such as `SAML_PROXY_BACKEND_URL`, are the equivalent environment variables that can be set instead of passing configuration via the command-line. \n\nThe command-line argument usage renders with only a single leading dash, but GNU-style double-dashes can be used also, such as `--sp-key-path`.\n\n## Authorization\n\nThe proxy has support for not only authenticating users via a SAML IdP, but can also further authorize access by evaluating the attributes included in the SAML response assertion.\n\nThe authorization is configured with the combination of `--authorize-attribute` and `--authorize-values`. \n\n**NOTE** the attribute is case sensitive, so be sure to specify that parameter exactly as it appears in the `Name` attribute of the `\u003csaml:Attribute\u003e` element.\n\nThe values are a comma separated list of authorized values and since the assertion attributes can contain more than one value also, the authorization performs an \"intersection\" matching any one of the expected values with any one of the assertion attribute values. That allows for matching user IDs where the assertion has a single value but you want to allow one or more users to be authorized. It also allows for matching group names where each user may be belong to more than one group and you may want to also authorize any number of groups.\n\nThe proxy also has [support for Traefik forward auth](https://doc.traefik.io/traefik/middlewares/http/forwardauth) and [the caddy variant](https://caddyserver.com/docs/caddyfile/directives/forward_auth). The `--auth-verify` and `--auth-verify-path` parameters can be used to enable a verify endpoint that will respond with a 204 when the user is authenticated.\n\n**WARNING** the `--auth-verify` option trusts the `X-Forwarded-*` headers and should only be used when the proxy is behind a gateway; one that clears and sets those headers.\n\n## Note for AJAX/Fetch Operations\n\nIf the web application being protected behind this proxy makes AJAX/Fetch calls, then be sure\nto enable \"same-origin\" access for the credentials of those calls, \nas described [here](https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials).\n\nWith that configuration in place, the AJAX/Fetch calls will leverage the same `token` cookie \nprovided in response to the first authenticated page retrieval via the proxy.\n\nWhen the user is authorized, the proxied request header `X-Authorized-Using` will be populated with the `attribute=value` that was matched, such as \n\n```\nX-Authorized-Using: UserID=user1\n```\n\n## Health Endpoint\n\nThe proxy itself provides a health endpoint at `/_health` that can be used to confirm the proxy is healthy/ready independent of the SAML processing. It returns a status code of 200 and a `text/plain` body with \"OK\".\n\n## Building\n\nWith Go 1.11 or newer:\n\n```\ngo build\n```\n\n## Trying it out\n\nThe following procedure will enable you to try out the proxy running locally and using\nGrafana as a backend to proxy with authentication. It will use [SSOCircle](https://www.ssocircle.com)\nas a SAML IdP.\n\nStart the supplied Grafana and Web Debug Server using Docker Compose:\n\n```bash\ndocker compose up -d\n```\n\nCreate a domain name that resolves to 127.0.0.1 and use that as the `BASE_FQDN` in the following\noperations;\n\nGenerate the SP certificate and key material by running:\n\n```bash\n# IMPORTANT: set this\nBASE_FQDN=...\nopenssl req -x509 -newkey rsa:2048 -keyout saml-auth-proxy.key -out saml-auth-proxy.cert -days 365 -nodes -subj \"/CN=${BASE_FQDN}\"\n```\n\nStart saml-auth-proxy using:\n\n```bash\n./saml-auth-proxy \\\n  --base-url http://${BASE_FQDN}:8080 \\\n  --backend-url http://localhost:3000 \\\n  --idp-metadata-url=https://idp.ssocircle.com/meta-idp.xml \\\n  --attribute-header-mappings UserID=x-webauth-user\n```\n\nGenerate your SP's SAML metadata by accessing the built-in metadata endpoint:\n\n```bash\ncurl http://localhost:8080/saml/metadata \u003e saml-sp-metadata.xml\n```\n\nor with PowerShell\n```ps\nInvoke-RestMethod -Uri http://localhost:8080/saml/metadata -OutFile .\\saml-sp-metadata.xml\n```\n\nYou can upload the  file `saml-sp-metadata.xml` file at \n[SSOCircle's Manage SP Meta Data](https://idp.ssocircle.com/sso/hos/ManageSPMetadata.jsp).\n\n**Note** you will also be selecting the attributes that will be included in the assertion in the SAML authentication response, such as: \n- `FirstName`\n- `LastName`\n- `EmailAddress`\n- `UserID`\n\nTo try out authorization you would add the following arguments referencing something like `UserID` and one or more expected SAMLTest user's values:\n\n```\n  --authorize-attribute UserID \\\n  --authorize-values user1,user2\n```\n\nNow you can open your browser and navigate to `http://${BASE_FQDN}:8080`. You will be redirected via SAMLTest's login page and then be returned with access to Grafana.\n\nForce a logout from the IdP by going to \u003chttps://idp.ssocircle.com/sso/UI/Logout\u003e\n\n## Troubleshooting\n\n### ERROR: failed to decrypt response\n\nIf the SAML redirect results in a \"Forbidden\" white-page and the saml-auth-proxy outputs a log like the following, then be sure to double check that the subject/CN of the generated certificate matches the FQDN of the deployed endpoint.\n\n```\nERROR: failed to decrypt response: crypto/rsa: decryption error\n```\n\nAfter correcting the certificate and key, be sure to regenerate the metadata and provide that to the ADFS/SAML IdP owner.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitzg%2Fsaml-auth-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fitzg%2Fsaml-auth-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitzg%2Fsaml-auth-proxy/lists"}