{"id":41128406,"url":"https://github.com/dyson/certman","last_synced_at":"2026-01-22T18:14:40.423Z","repository":{"id":32503209,"uuid":"99016273","full_name":"dyson/certman","owner":"dyson","description":"Go TLS certificate reloading for the standard library http server.","archived":false,"fork":false,"pushed_at":"2023-05-29T07:07:36.000Z","size":22,"stargazers_count":31,"open_issues_count":4,"forks_count":5,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-06-18T17:05:18.040Z","etag":null,"topics":["certificate","go","https","livereload","tls"],"latest_commit_sha":null,"homepage":"https://github.com/dyson/certman","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/dyson.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-08-01T15:29:35.000Z","updated_at":"2024-05-01T22:16:02.000Z","dependencies_parsed_at":"2024-06-18T17:11:11.581Z","dependency_job_id":null,"html_url":"https://github.com/dyson/certman","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/dyson/certman","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dyson%2Fcertman","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dyson%2Fcertman/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dyson%2Fcertman/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dyson%2Fcertman/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dyson","download_url":"https://codeload.github.com/dyson/certman/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dyson%2Fcertman/sbom","scorecard":{"id":362517,"data":{"date":"2025-08-11","repo":{"name":"github.com/dyson/certman","commit":"d38fd5a37a55e5f465b31c63674a5362a8b769f8"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"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":"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":"Code-Review","score":0,"reason":"Found 0/23 approved changesets -- score normalized to 0","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":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"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":"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":"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":"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":"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":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: 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":"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"}}]},"last_synced_at":"2025-08-18T11:09:15.835Z","repository_id":32503209,"created_at":"2025-08-18T11:09:15.835Z","updated_at":"2025-08-18T11:09:15.835Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28667881,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-22T17:07:18.858Z","status":"ssl_error","status_checked_at":"2026-01-22T17:05:02.040Z","response_time":144,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: 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":["certificate","go","https","livereload","tls"],"created_at":"2026-01-22T18:14:39.905Z","updated_at":"2026-01-22T18:14:40.415Z","avatar_url":"https://github.com/dyson.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Certman\n\n![version](https://img.shields.io/github/v/tag/dyson/certman?label=version)\n[![Build Status](https://travis-ci.org/dyson/certman.svg?branch=master)](https://travis-ci.org/dyson/certman)\n[![Coverage Status](https://coveralls.io/repos/github/dyson/certman/badge.svg?branch=master)](https://coveralls.io/github/dyson/certman?branch=master)\n[![Code Climate](https://codeclimate.com/github/dyson/certman/badges/gpa.svg)](https://codeclimate.com/github/dyson/certman)\n[![Go Report Card](https://goreportcard.com/badge/github.com/dyson/certman)](https://goreportcard.com/report/github.com/dyson/certman)\n\n[![GoDoc](https://godoc.org/github.com/dyson/certman?status.svg)](http://godoc.org/github.com/dyson/certman)\n[![license](https://img.shields.io/github/license/dyson/certman.svg)](https://github.com/dyson/certman/blob/master/LICENSE)\n\nGo TLS certificate reloading for the standard library http server.\n\nCertman watches for changes to your certificate and key files and reloads them on change allowing the server to stay online during certificate changes. Useful for Let's Encrypt but also just in general as there's no reason to bring your servers down just to update certificates and keys.\n\n## Limitation\n\nCertman handles only a single certificate and key pair and responds to all requests with this pair. It ignores if the client is sending a server name using SNI. I'm not sure if there's a generic enough way to implement this that handles all use cases and as it's a niche feature I haven't needed so I've left it out (pull requests welcome!). Certman's codebase is small so either fork the repo or copy and paste it into your project and modify it to your needs.\n\n## Installation\nUsing dep for dependency management (https://github.com/golang/dep):\n```\ndep ensure github.com/dyson/certman\n```\n\nUsing go get:\n```\n$ go get github.com/dyson/certman\n```\n## Usage\n\nGenerate a cert and key:\n\n```\n$ openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -sha256 -keyout /tmp/server.key -out /tmp/server.crt\n```\nBasic server passing in a logger to log certman events:\n```go\npackage main\n\nimport (\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n\n\t\"github.com/dyson/certman\"\n)\n\nfunc main() {\n\tlogger := log.New(os.Stdout, \"\", log.LstdFlags)\n\n\tcm, err := certman.New(\"/tmp/server.crt\", \"/tmp/server.key\")\n\tif err != nil {\n\t\tlogger.Println(err)\n\t}\n\tcm.Logger(logger)\n\tif err := cm.Watch(); err != nil {\n\t\tlogger.Println(err)\n\t}\n\n\thttp.HandleFunc(\"/\", handler)\n\ts := \u0026http.Server{\n\t\tAddr: \":8080\",\n\t\tTLSConfig: \u0026tls.Config{\n\t\t\tGetCertificate: cm.GetCertificate,\n\t\t},\n\t}\n\tif err := s.ListenAndServeTLS(\"\", \"\"); err != nil {\n\t\tlogger.Println(err)\n\t}\n}\n\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintf(w, \"Hello\")\n}\n```\nVisit https://localhost:8080.\n\nOverwrite exising certificate and key using the openssl gen command above.\n\nVisit https://localhost:8080 again. Notice how existing requests are continued to be served by the old certificate.\n\nVisit https://localhost:8080 in another browser and see the new certificate is being served for new requests.\n\nRunning example:\n```\n$ go run main.go\n2017/08/01 16:05:23 certman: certificate and key loaded\n2017/08/01 16:05:23 certman: watching for cert and key change\n# Regenerated certificate and key here\n2017/08/01 16:06:30 certman: watch event: \"/tmp/server.key\": WRITE\n2017/08/01 16:06:30 certman: can't load cert or key file: tls: private key does not match public key\n2017/08/01 16:06:30 certman: watch event: \"/tmp/server.key\": WRITE\n2017/08/01 16:06:30 certman: can't load cert or key file: tls: private key does not match public key\n2017/08/01 16:06:32 certman: watch event: \"/tmp/server.crt\": WRITE\n2017/08/01 16:06:32 certman: certificate and key loaded\n# Certificate loaded once the certificate and key can both be read correctly and they match\n```\n\n## License\nSee LICENSE file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdyson%2Fcertman","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdyson%2Fcertman","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdyson%2Fcertman/lists"}