{"id":28389765,"url":"https://github.com/ccesarfp/shrine","last_synced_at":"2026-04-11T06:02:12.529Z","repository":{"id":217520332,"uuid":"742916145","full_name":"ccesarfp/Shrine","owner":"ccesarfp","description":"Token Management Microservice with Redis Database and gRPC","archived":false,"fork":false,"pushed_at":"2024-04-19T13:11:09.000Z","size":19664,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-31T11:36:11.939Z","etag":null,"topics":["docker","docker-compose","go","golang","grpc","redis"],"latest_commit_sha":null,"homepage":"","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/ccesarfp.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":"2024-01-13T18:47:05.000Z","updated_at":"2024-01-18T00:11:44.000Z","dependencies_parsed_at":"2024-03-14T12:30:36.782Z","dependency_job_id":"f7364de4-b5cc-4de4-8e55-480a05b4bf71","html_url":"https://github.com/ccesarfp/Shrine","commit_stats":null,"previous_names":["ccesarfp/shrine"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ccesarfp/Shrine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ccesarfp%2FShrine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ccesarfp%2FShrine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ccesarfp%2FShrine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ccesarfp%2FShrine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ccesarfp","download_url":"https://codeload.github.com/ccesarfp/Shrine/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ccesarfp%2FShrine/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262335785,"owners_count":23295737,"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":["docker","docker-compose","go","golang","grpc","redis"],"created_at":"2025-05-31T02:08:48.652Z","updated_at":"2025-12-30T22:17:17.146Z","avatar_url":"https://github.com/ccesarfp.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"Shrine Logo\" src=\"https://drive.google.com/uc?export=view\u0026id=1p9ZayHmx9gldSom-VAnBPO9sHcGlSHIh\" width=\"650px\" /\u003e\n  \u003ch1 align=\"center\"\u003eShrine\u003c/h1\u003e\n\u003c/p\u003e\n\n## What is It?\nShrine is an authentication microservice that enables the rapid and secure creation of JWT tokens. \n\nIt utilizes gRPC communication and stores data in Redis.\n\n## Example Architecture\n\n\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"Architecture Diagram\" src=\"https://drive.google.com/uc?export=view\u0026id=1a7duFkkFd4hPUVfX0raTU3NFmNjwq7i3\" width=\"700px\" /\u003e\n\u003c/p\u003e\n\n## How it Works?\n\n\u003cdetails open\u003e\n\u003csummary\u003eFirst case\u003c/summary\u003e\nA user accesses for the first time (or is not authenticated), then their access data is sent to the main application, which redirects to the Shrine. The Shrine generates an opaque token and a JWT with the user's IP address data. Finally, the opaque token is returned to the user to be used as an access token.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eSecond case\u003c/summary\u003e\nAfter accessing for the first time, this user registers (or logs in) and their authentication data is sent to the main server. Once the main system confirms who the user is, it creates a JWT with all the data it will need for internal use and then directs this token to the Shrine, which updates the Opaque Token to store this new JWT.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eThird case\u003c/summary\u003e\nThis user has just accessed their profile and made a change to their name, so their updated data is sent to the main application (and their Opaque Token accompanies it). Upon arriving at the main application, this Opaque Token is redirected to the Shrine, which finds its previously stored JWT and sends it back to the main application, allowing it to continue saving the new data.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eFourth case\u003c/summary\u003e\nAfter a few days, the user accessed the application again to make a new change to their profile, but now, due to the time without access, their token was revoked. To deal with this, the Shrine notifies the main application, after trying to find its old Opaque Token, that it will take the user back to the authentication screen.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eFifth case\u003c/summary\u003e\nWhile processing data, the main application was unsure whether that user should still be accessing the system or not. Therefore, it forwards this Opaque Token to the Shrine, which checks its validity and notifies the main application about its current status.\n\u003c/details\u003e\n\n## How to Install?\n\nFirstly, ensure that you have Docker installed and running.\n\nBy default, Redis will be started on port **6379** and will be created with the password **123**.\n\nRename the file **.env.example** to **.env**.\n\nAccess the **.env** file and include the **secret phrase (JWT_SECRET_KEY)** without spaces, this phrase will be used for JWT creation.\n\nInside the project folder, execute the following command:\n```bash\n  docker-compose up\n```\nNow Docker will download the Redis image and build our Shrine image. After finishing the service will start.\n\nAnd that's it, the Shrine is up and running and ready to use.\n\nFor testing, you can use applications like **Postman**. Just import the **Token.proto** file.\n\n## gRPC Documentation\n\n\u003cdetails\u003e\n\u003csummary\u003eToken.proto\u003c/summary\u003e\n\n  #### Token  Service\n  | Method | Request | Response | Description                                 |\n  | --- | --- | --- |---|\n  | CreateToken  | UserRequest | UserResponse | Create token using user data and return JWT |\n  | UpdateToken | UserUpdateRequest | UserResponse | Receive opaque token and update linked jwt  |\n  | GetJwt  | TokenRequest | TokenResponse | Receive opaque token and return user jwt    |\n  | CheckTokenValidity  | TokenRequest | TokenStatus | Receive token and return if is valid        |\n  \n  \u003cdetails\u003e\n  \u003csummary\u003eUserRequest\u003c/summary\u003e\n    \n  Request message for CreateToken\n  | Field | Type | Description |\n  | --- | --- | --- |\n  | hoursToExpire  | int32 | Token duration |\n  \n  \u003c/details\u003e\n  \n  \n  \u003cdetails\u003e\n  \u003csummary\u003eUserUpdateRequest\u003c/summary\u003e\n    \n  Request message for UpdateToken\n  | Field | Type | Description |\n  | --- | --- | --- |\n  | token | string | User opaque token |\n  | jwt | string | User jwt |\n  | hoursToExpire | int32 | Token duration |\n  \n  \u003c/details\u003e\n  \n  \n  \u003cdetails\u003e\n  \u003csummary\u003eTokenRequest\u003c/summary\u003e\n  \n  Request message for GetJwt and CheckTokenValidity\n  | Field | Type | Description |\n  | --- | --- | --- |\n  | token | string | Opaque token |\n  \n  \u003c/details\u003e\n\n  \u003cdetails\u003e\n  \u003csummary\u003eUserResponse\u003c/summary\u003e\n  \n  Response message for CreateToken and UpdateToken\n  | Field | Type | Description |\n  | --- | --- | --- |\n  | token | string | User opaque token |\n  \n  \u003c/details\u003e\n\n  \u003cdetails\u003e\n  \u003csummary\u003eTokenResponse\u003c/summary\u003e\n\n  Response message for GetJwt\n  | Field | Type | Description |\n  | --- | --- | --- |\n  | jwt | string | User jwt |\n\n  \u003c/details\u003e\n  \n  \u003cdetails\u003e\n  \u003csummary\u003eTokenStatus\u003c/summary\u003e\n  \n  Response message for CheckTokenValidity\n  | Field | Type | Description |\n  | --- | --- | --- |\n  | status | bool | Token status |\n  \n  \u003c/details\u003e\n\n\u003c/details\u003e\n\n## Why Does the Shrine Exist?\n\nThe Shrine was designed with the aim of creating a service that could be used by multiple applications, avoiding the need to develop a token management system for each of them. \n\nThe choice to use the Go language stemmed from the desire to enhance my knowledge in it, coupled with its high execution speed. \n\nAdditionally, the decision was made to implement gRPC and utilize the Redis database for the temporary persistence of these tokens.\n\n## What Did I Learn?\n\nWith this project, I could realize how enjoyable it is to program using Golang, both in creating gRPC servers and integrating with Redis.\n\nBeyond the technical aspects of development, I was able to enhance my architectural vision. Throughout the entire development process, I consistently thought about how the system could integrate with other applications and what role it should play within a complete architecture.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fccesarfp%2Fshrine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fccesarfp%2Fshrine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fccesarfp%2Fshrine/lists"}