{"id":21616158,"url":"https://github.com/hsson/ring","last_synced_at":"2025-03-18T17:20:07.253Z","repository":{"id":85431848,"uuid":"318001922","full_name":"hsson/ring","owner":"hsson","description":"Automated rotation of RSA signing keys","archived":false,"fork":false,"pushed_at":"2020-12-10T20:31:56.000Z","size":37,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-24T20:46:16.022Z","etag":null,"topics":["cryptography","key-rotation","rsa"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hsson.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":"2020-12-02T21:55:49.000Z","updated_at":"2020-12-06T16:43:43.000Z","dependencies_parsed_at":"2024-06-20T05:44:52.627Z","dependency_job_id":"f69463f8-b8bd-40b5-bcd7-e233852e3beb","html_url":"https://github.com/hsson/ring","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hsson%2Fring","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hsson%2Fring/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hsson%2Fring/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hsson%2Fring/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hsson","download_url":"https://codeload.github.com/hsson/ring/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244267475,"owners_count":20425835,"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","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":["cryptography","key-rotation","rsa"],"created_at":"2024-11-24T22:13:50.575Z","updated_at":"2025-03-18T17:20:07.221Z","avatar_url":"https://github.com/hsson.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hsson/ring\n\n**WORK IN PROGRESS**: This project is not in a production ready state, please await v1.0.0.\n\n[![PkgGoDev](https://pkg.go.dev/badge/github.com/hsson/ring)](https://pkg.go.dev/github.com/hsson/ring) [![GoReportCard](https://goreportcard.com/badge/github.com/hsson/ring)](https://goreportcard.com/report/github.com/hsson/ring)\n\nAutomatically rotate signing keys with ease.\n\n## Thread safety\n`hsson/ring` is completely thread safe. If using `hsson/ring` in just a single instance of your application, there will only ever be a single signing key active at any given time. However, there are no cross-instance/node synchronization, so if using `hsson/ring` on multiple instances of your application, there might be more than a single signing key active at a given moment, this is however completely fine, it will just add more data in your database.\n\n## Examples\n### Example of JWT signing with `dgrijalva/jwt-go`\nBelow is an example of using `hsson/ring` together with `dgrijalva/jwt-go` to achieve automatic rotation of keys when signing JWT access tokens.\n\nFirst create an instance of the Ring keychain. Can be done once at the initialization step of your application:\n```go\nr := ring.New()\n```\nthen sign your JWT:\n```go\n// Get a signing key from Ring\nringSigningKey, err := r.SigningKey()\nif err != nil {\n  // ...\n}\n\n// Create the token\ntoken := jwt.New(jwt.GetSigningMethod(\"HS256\"))\n// Set the Key ID header so we can later get the correct verifier key\ntoken.Header[\"kid\"] = ringSigningKey.ID\n\n// Set JWT expiration time, and cap it to our signing keys max verification time\nexp := time.Now().Add(time.Hour * 72)\nif exp.After(ringSinginKey.VerifiableUntil) {\n  exp = ringSigningKey.VerifiableUntil\n}\ntoken.Claims[\"exp\"] = exp.Unix()\n\n// Sign and get the complete encoded token as a string\ntokenString, err := token.SignedString(ringSigningKey.Key)\n```\n\n### Example of JWT validation with `dgrijalva/jwt-go`\nBelow is an example of how to verify a JWT previously signed using a key provided by `hsson/ring`.\n\nFirst create an instance of the Ring keychain. Can be done once at the initialization step of your application. It does not have to be the exact same instance as the one used to sign your JWT, as long as the instances share the same underlying store:\n```go\nr := ring.New()\n```\nthen in your authentication middleware:\n```go\nmyTokenString := ... // Get from e.g. the Authorization header\ntoken, err := jwt.Parse(myTokenString, func(token *jwt.Token) ([]byte, error) {\n  keyID := token.Header[\"kid\"]\n  publicKey, err := r.GetVerifier(keyID)\n  if err != nil {\n    return nil, err\n  }\n  return publicKey.EncodeToPEM(), nil\n})\n\nif err == nil \u0026\u0026 token.Valid {\n  // Success\n} else {\n  // Invalid token\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhsson%2Fring","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhsson%2Fring","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhsson%2Fring/lists"}