{"id":40337016,"url":"https://github.com/spacemonkeygo/httpsig","last_synced_at":"2026-01-20T08:35:52.684Z","repository":{"id":57479877,"uuid":"83375021","full_name":"spacemonkeygo/httpsig","owner":"spacemonkeygo","description":"HTTP Signature library for Golang","archived":false,"fork":false,"pushed_at":"2024-07-25T08:24:13.000Z","size":23,"stargazers_count":23,"open_issues_count":7,"forks_count":18,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-08-13T22:31:15.454Z","etag":null,"topics":["cavage","go","golang","httpsig"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spacemonkeygo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-28T01:25:42.000Z","updated_at":"2025-01-02T20:40:01.000Z","dependencies_parsed_at":"2022-09-26T17:41:32.925Z","dependency_job_id":null,"html_url":"https://github.com/spacemonkeygo/httpsig","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/spacemonkeygo/httpsig","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spacemonkeygo%2Fhttpsig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spacemonkeygo%2Fhttpsig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spacemonkeygo%2Fhttpsig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spacemonkeygo%2Fhttpsig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spacemonkeygo","download_url":"https://codeload.github.com/spacemonkeygo/httpsig/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spacemonkeygo%2Fhttpsig/sbom","scorecard":{"id":840018,"data":{"date":"2025-08-11","repo":{"name":"github.com/spacemonkeygo/httpsig","commit":"2605ae379e47a0fb29fb444c1c0902043fbaf267"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.6,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","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":"Code-Review","score":4,"reason":"Found 3/7 approved changesets -- score normalized to 4","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":"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":-1,"reason":"No tokens found","details":null,"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":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"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":"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":"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":"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":"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":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"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":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 7 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-23T20:14:25.574Z","repository_id":57479877,"created_at":"2025-08-23T20:14:25.574Z","updated_at":"2025-08-23T20:14:25.574Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28599117,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T02:08:49.799Z","status":"ssl_error","status_checked_at":"2026-01-20T02:08:44.148Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["cavage","go","golang","httpsig"],"created_at":"2026-01-20T08:35:52.551Z","updated_at":"2026-01-20T08:35:52.671Z","avatar_url":"https://github.com/spacemonkeygo.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# HTTPSIG for Go\n\nThis library implements HTTP request signature generation and verification based on\nthe RFC draft specification https://tools.ietf.org/html/draft-cavage-http-signatures-06.\n\nThe library strives be compatible with the popular python library of the same\nname: https://github.com/ahknight/httpsig\n\n## Installing\n\n```\ngo get gopkg.in/spacemonkeygo/httpsig.v0\n```\n\n## Signing Requests\n\nSigning requests is done by constructing a new `Signer`. The key id, key,\nalgorithm, and what headers to sign are required.\n\nFor example to construct a `Signer` with key id `\"foo\"`, using an RSA private\nkey, for the rsa-sha256 algorithm, with the default header set, you can do:\n\n```\nvar key *rsa.PrivateKey = ...\nsigner := httpsig.NewSigner(\"foo\", key, httpsig.RSASHA256, nil)\n```\n\nThere are helper functions for specific algorithms that are less verbose and\nprovide more type safety (the key paramater need not be of type `interface{}`\nbecause the type required for the algorithm is known).\n\n```\nvar key *rsa.PrivateKey = ...\nsigner := httpsig.NewRSASHA256Signer(\"foo\", key, nil)\n```\n\nBy default, if no headers are passed to `NewSigner` (or the helpers), the\n`(request-target)` pseudo-header and `Date` header are signed.\n\nTo sign requests, call the `Sign()` method. The method signs the request and\nadds an `Authorization` header containing the signature parameters.\n\n```\nerr = signer.Sign(req)\nif err != nil {\n    ...\n}\nfmt.Println(\"AUTHORIZATION:\", req.Header.Get('Authorization'))\n\n...\n\nAUTHORIZATION: Signature: keyId=\"foo\",algorithm=\"sha-256\",signature=\"...\"\n\n```\n\n## Verifying Requests\n\nVerifying requests is done by constructing a new `Verifier`. The verifier\nrequires a KeyGetter implementation to look up keys based on `keyId`'s\nretrieved from signature parameters.\n\n```\nvar getter httpsig.KeyGetter = ....\nverifier := httpsig.NewVerifier(getter)\n```\n\nA request can be verified by calling the `Verify()` method:\n\n```\nerr = verifier.Verify(req)\n```\n\nBy default, the verifier only requires the `Date` header to be included\nin the signature. The set of required headers be changed using the\n`SetRequiredHeaders()` method to enforce stricter requirements.\n\n```\nverifier.SetRequiredHeaders([]string{\"(request-target)\", \"host\", \"date\"})\n```\n\nRequests that don't include the full set of required headers in the `headers`\nsignature parameter (either implicity or explicity) will fail verification.\n\n**Note that required headers are simply a specification for which headers must\nbe included in the signature, and does not enforce header presence in requests.\nIt is up to callers to validate header contents (or the lack thereof).**\n\nA simple in-memory key store is provided by the library and can be constructed\nwith the `NewMemoryKeyStore()` function. Keys can be added using the SetKey\nmethod:\n```\nkeystore := NewMemoryKeyStore()\n\nvar rsa_key *rsa.PublicKey = ...\nkeystore.SetKey(\"foo\", rsa_key)\n\nvar hmac_key []byte = ...\nkeystore.SetKey(\"foo\", hmac_key)\n```\n\n## Handler\n\nA convenience function is provided that wraps an `http.Handler` and verifies\nincoming request signatures before passing them down to the wrapped handler.\n\nIf requires a verifier and optionally a realm (for constructing the\n`WWW-Authenticate` header).\n\n```\nvar handler http.Handler = ...\nvar verifier *httpsig.Verifier = ...\nwrapped := httpsig.RequireSignature(handler, verifier, \"example.com\")\n```\n\nIf signature validation fails, a `401` is returned along with a\n`WWW-Authenticate` header containing  a `Signature` challenge with optional\n`realm` and `headers` parameters.\n\n## Supported algorithms\n\n- rsa-sha1 (using PKCS1v15)\n- rsa-sha256 (using PKCS1v15)\n- hmac-sha256\n\n### License\n\nCopyright (C) 2017 Space Monkey, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n  http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspacemonkeygo%2Fhttpsig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspacemonkeygo%2Fhttpsig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspacemonkeygo%2Fhttpsig/lists"}