{"id":16863771,"url":"https://github.com/aidantwoods/go-paseto","last_synced_at":"2025-05-16T07:06:23.812Z","repository":{"id":37954344,"uuid":"418266120","full_name":"aidantwoods/go-paseto","owner":"aidantwoods","description":"Platform-Agnostic Security Tokens implementation in Golang.","archived":false,"fork":false,"pushed_at":"2025-04-14T18:55:22.000Z","size":254,"stargazers_count":367,"open_issues_count":7,"forks_count":19,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-05-08T19:51:45.472Z","etag":null,"topics":["go","go-paseto","golang","paseto","security","token"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/aidanwoods.dev/go-paseto","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/aidantwoods.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"aidantwoods"}},"created_at":"2021-10-17T22:01:50.000Z","updated_at":"2025-05-08T18:39:55.000Z","dependencies_parsed_at":"2025-01-19T22:05:35.023Z","dependency_job_id":"488f6936-0298-4a75-9e0c-be3ec3938f05","html_url":"https://github.com/aidantwoods/go-paseto","commit_stats":{"total_commits":148,"total_committers":6,"mean_commits":"24.666666666666668","dds":"0.22972972972972971","last_synced_commit":"3b1f947fd0f3bb51959eeaac4129d41f08373682"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidantwoods%2Fgo-paseto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidantwoods%2Fgo-paseto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidantwoods%2Fgo-paseto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidantwoods%2Fgo-paseto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aidantwoods","download_url":"https://codeload.github.com/aidantwoods/go-paseto/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254485063,"owners_count":22078767,"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":["go","go-paseto","golang","paseto","security","token"],"created_at":"2024-10-13T14:39:41.492Z","updated_at":"2025-05-16T07:06:18.792Z","avatar_url":"https://github.com/aidantwoods.png","language":"Go","funding_links":["https://github.com/sponsors/aidantwoods"],"categories":[],"sub_categories":[],"readme":"# Go Paseto [![Go-Paseto](https://github.com/aidantwoods/go-paseto/actions/workflows/ci.yml/badge.svg)](https://github.com/aidantwoods/go-paseto/actions/workflows/ci.yml)\n\nA Go implementation of [PASETO](https://github.com/paragonie/paseto).\n\nPaseto is everything you love about JOSE (JWT, JWE, JWS) without any of the\n[many design deficits that plague the JOSE standards](https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-bad-standard-that-everyone-should-avoid).\n\n\n# Contents\n* [What is Paseto?](#what-is-paseto)\n  * [Key Differences between Paseto and JWT](#key-differences-between-paseto-and-jwt)\n* [Installation](#installation)\n* [Overview of the Go library](#overview-of-the-go-library)\n* [Supported Paseto Versions](#supported-paseto-versions)\n\n# What is Paseto?\n\n[Paseto](https://github.com/paragonie/paseto) (Platform-Agnostic SEcurity\nTOkens) is a specification for secure stateless tokens.\n\n## Key Differences between Paseto and JWT\n\nUnlike JSON Web Tokens (JWT), which gives developers more than enough rope with\nwhich to hang themselves, Paseto only allows secure operations. JWT gives you\n\"algorithm agility\", Paseto gives you \"versioned protocols\". It's incredibly\nunlikely that you'll be able to use Paseto in\n[an insecure way](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries).\n\n\u003e **Caution:** Neither JWT nor Paseto were designed for\n\u003e [stateless session management](http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/).\n\u003e Paseto is suitable for tamper-proof cookies, but cannot prevent replay attacks\n\u003e by itself.\n\n# Installation\n\n```bash\ngo get -u aidanwoods.dev/go-paseto\n```\n\n# Overview of the Go library\n\nOkay, let's create a token:\n```go\ntoken := paseto.NewToken()\n\ntoken.SetIssuedAt(time.Now())\ntoken.SetNotBefore(time.Now())\ntoken.SetExpiration(time.Now().Add(2 * time.Hour))\n\ntoken.SetString(\"user-id\", \"\u003cuuid\u003e\")\n```\n\nNow encrypt it:\n```go\nkey := paseto.NewV4SymmetricKey() // don't share this!!\n\nencrypted := token.V4Encrypt(key, nil)\n```\n\nOr sign it (this allows recievers to verify it without sharing secrets):\n```go\n\nsecretKey := paseto.NewV4AsymmetricSecretKey() // don't share this!!!\npublicKey := secretKey.Public() // DO share this one\n\nsigned := token.V4Sign(secretKey, nil)\n```\n\nTo handle a recieved token, let's use an example from Paseto's test vectors:\n\nThe Paseto token is as follows\n```\nv4.public.eyJkYXRhIjoidGhpcyBpcyBhIHNpZ25lZCBtZXNzYWdlIiwiZXhwIjoiMjAyMi0wMS0wMVQwMDowMDowMCswMDowMCJ9v3Jt8mx_TdM2ceTGoqwrh4yDFn0XsHvvV_D0DtwQxVrJEBMl0F2caAdgnpKlt4p7xBnx1HcO-SPo8FPp214HDw.eyJraWQiOiJ6VmhNaVBCUDlmUmYyc25FY1Q3Z0ZUaW9lQTlDT2NOeTlEZmdMMVc2MGhhTiJ9\n```\n\nAnd the public key, given in hex is:\n```\n1eb9dbbbbc047c03fd70604e0071f0987e16b28b757225c11f00415d0e20b1a2\n```\n\nImporting a public key, and then verifying a token:\n\n```go\npublicKey, err := paseto.NewV4AsymmetricPublicKeyFromHex(\"1eb9dbbbbc047c03fd70604e0071f0987e16b28b757225c11f00415d0e20b1a2\") // this wil fail if given key in an invalid format\nsigned := \"v4.public.eyJkYXRhIjoidGhpcyBpcyBhIHNpZ25lZCBtZXNzYWdlIiwiZXhwIjoiMjAyMi0wMS0wMVQwMDowMDowMCswMDowMCJ9v3Jt8mx_TdM2ceTGoqwrh4yDFn0XsHvvV_D0DtwQxVrJEBMl0F2caAdgnpKlt4p7xBnx1HcO-SPo8FPp214HDw.eyJraWQiOiJ6VmhNaVBCUDlmUmYyc25FY1Q3Z0ZUaW9lQTlDT2NOeTlEZmdMMVc2MGhhTiJ9\"\n\nparser := paseto.NewParserWithoutExpiryCheck() // only used because this example token has expired, use NewParser() (which checks expiry by default)\ntoken, err := parser.ParseV4Public(publicKey, signed, nil) // this will fail if parsing failes, cryptographic checks fail, or validation rules fail\n\n// the following will succeed\nrequire.JSONEq(t,\n    \"{\\\"data\\\":\\\"this is a signed message\\\",\\\"exp\\\":\\\"2022-01-01T00:00:00+00:00\\\"}\",\n    string(token.ClaimsJSON()),\n)\nrequire.Equal(t,\n    \"{\\\"kid\\\":\\\"zVhMiPBP9fRf2snEcT7gFTioeA9COcNy9DfgL1W60haN\\\"}\",\n    string(token.Footer()),\n)\nrequire.NoError(t, err)\n```\n\n# Supported Claims Validators\nThe following validators are supported:\n\n```go\nfunc ForAudience(audience string) Rule\nfunc IdentifiedBy(identifier string) Rule\nfunc IssuedBy(issuer string) Rule\nfunc NotExpired() Rule\nfunc Subject(subject string) Rule\nfunc ValidAt(t time.Time) Rule\n```\n\nA token using claims all the claims which can be validated can be constructed as follows:\n\n```go\ntoken := paseto.NewToken()\n\ntoken.SetAudience(\"audience\")\ntoken.SetJti(\"identifier\")\ntoken.SetIssuer(\"issuer\")\ntoken.SetSubject(\"subject\")\n\ntoken.SetExpiration(time.Now().Add(time.Minute))\ntoken.SetNotBefore(time.Now())\ntoken.SetIssuedAt(time.Now())\n\nsecretKeyHex := \"b4cbfb43df4ce210727d953e4a713307fa19bb7d9f85041438d9e11b942a37741eb9dbbbbc047c03fd70604e0071f0987e16b28b757225c11f00415d0e20b1a2\"\nsecretKey, _ := paseto.NewV4AsymmetricSecretKeyFromHex(secretKeyHex)\n\nsigned := token.V4Sign(secretKey, nil)\n```\n\nThe token in `signed` can then be validated using a public key as follows:\n```go\nparser := paseto.NewParser()\nparser.AddRule(paseto.ForAudience(\"audience\"))\nparser.AddRule(paseto.IdentifiedBy(\"identifier\"))\nparser.AddRule(paseto.IssuedBy(\"issuer\"))\nparser.AddRule(paseto.Subject(\"subject\"))\nparser.AddRule(paseto.NotExpired())\nparser.AddRule(paseto.ValidAt(time.Now()))\n\npublicKeyHex := \"1eb9dbbbbc047c03fd70604e0071f0987e16b28b757225c11f00415d0e20b1a2\"\npublicKey, err := paseto.NewV4AsymmetricPublicKeyFromHex(publicKeyHex)\nif err != nil {\n    // panic or deal with error of invalid key\n}\n\nparsedToken, err := parser.ParseV4Public(publicKey, signed, nil)\nif err != nil {\n    // deal with error of token which failed to be validated, or cryptographically verified\n}\n```\n\nIf everything succeeds, the value in `parsedToken` will be equivalent to that in `token`.\n\n# Supported Paseto Versions\n## Version 4\nVersion 4 is fully supported.\n## Version 3\nVersion 3 is fully supported.\n## Version 2\nVersion 2 is fully supported.\n\n# Supported Go Versions\nOnly [officially supported](https://go.dev/doc/devel/release#policy) versions of Go will be\nsupported by Go Paseto. Versions of Go which have recently gone out of support may continue to work\nwith this library for some time, however this is not guarenteed and should not be relied on.\n\nWhen support for an out of date version of Go is dropped, this will be done as part of a minor\nversion bump.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faidantwoods%2Fgo-paseto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faidantwoods%2Fgo-paseto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faidantwoods%2Fgo-paseto/lists"}