{"id":31897929,"url":"https://github.com/jcmturner/grpckrb","last_synced_at":"2025-10-13T11:49:30.158Z","repository":{"id":49110965,"uuid":"317506384","full_name":"jcmturner/grpckrb","owner":"jcmturner","description":"GRPC interceptors for Kerberos authentication","archived":false,"fork":false,"pushed_at":"2021-06-28T16:11:18.000Z","size":17,"stargazers_count":6,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-06-20T10:06:24.890Z","etag":null,"topics":["grpc","grpc-go","kerberos"],"latest_commit_sha":null,"homepage":"","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/jcmturner.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":"2020-12-01T10:32:46.000Z","updated_at":"2024-01-26T15:46:03.000Z","dependencies_parsed_at":"2022-09-24T02:42:49.946Z","dependency_job_id":null,"html_url":"https://github.com/jcmturner/grpckrb","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/jcmturner/grpckrb","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcmturner%2Fgrpckrb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcmturner%2Fgrpckrb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcmturner%2Fgrpckrb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcmturner%2Fgrpckrb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jcmturner","download_url":"https://codeload.github.com/jcmturner/grpckrb/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcmturner%2Fgrpckrb/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279014818,"owners_count":26085595,"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","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["grpc","grpc-go","kerberos"],"created_at":"2025-10-13T11:49:18.388Z","updated_at":"2025-10-13T11:49:30.150Z","avatar_url":"https://github.com/jcmturner.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# grpckrb\n\ngrpckrb provides the client and server interceptors required to implement Kerberos based authentication for GRPC.\n\nThese interceptors make use of the [gokrb5](https://github.com/jcmturner/gokrb5) library.\nPlease refer to the documentation there for more information.\n\n## Server side configuration\n\n1. Load the service's keytab\n2. Create gokrb5 service settings\n3. Create a ``grpckrb.KRBServerInterceptor`` with the service settings\n4. Create a new GRPC server with the UnaryInterceptor and StreamInterceptor server options set.\n\n```go\nimport (\n    \"github.com/jcmturner/gokrb5/v8/keytab\"\n    \"github.com/jcmturner/gokrb5/v8/service\"\n)\n\nkt, _ := keytab.Load(\"path/to/keytab/file\")\n\nsi := \u0026grpckrb.KRBServerInterceptor{\n\tSettings: service.NewSettings(kt),\n}\n\nopts := []grpc.ServerOption{\n\tgrpc.UnaryInterceptor(si.Unary()),\n\tgrpc.StreamInterceptor(si.Stream()),\n}\n\ngrpcSrv := grpc.NewServer(opts...)\n```\n\n### Authorization\nWithout any authorization settings any valid authenticated user will have access to all GRPC methods.\n\nA map of GRPC methods to authorising attributes can be added to the ``grpckrb.KRBServerInterceptor`` object:\n\n```go\nauthzRoles := make(map[string][]string)\nauthzRoles[\"/Service/Reflector\"] = []string{\"testuser1@TEST.GOKRB5\"}\nauthzRoles[\"/Service/Mirror\"] = []string{\"testuser1@TEST.GOKRB5\"}\n\nsi := \u0026grpckrb.KRBServerInterceptor{\n\tSettings:           service.NewSettings(kt),\n\tAuthorizationRoles: authzRoles,\n}\n```\nThe authorising attributes can be user principal names or,\nif Active Directory is being used as the KDC, SIDs of AD groups.\n\n#### Anonymuos access\nBy default any GRPC methods that do not have any authorization settings in the map will be accessible to any valid authenticated user.\nIf desired they can be made accessible to anonymous users by setting the ``AllowAnonymous`` field of the\n``grpckrb.KRBServerInterceptor`` to true:\n```go\nsi := \u0026grpckrb.KRBServerInterceptor{\n\tSettings:       service.NewSettings(kt),\n\tAllowAnonymous: true,\n}\n```\n\n### Best Practices\n#### Logging\nIt is recommended to implement a logger on the server side. This can be done through the gokrb5 service settings:\n```go\nl := log.New(os.Stdout, \"KRB Auth: \", log.LstdFlags)\n\nsi := \u0026grpckrb.KRBServerInterceptor{\n\tSettings: service.NewSettings(kt, service.Logger(l)),\n}\n```\n\n## Client side configuration\n1. Load the clients keytab\n2. Load the client krb5.conf\n3. Create a gokrb5 client\n4. Create a ``grpckrb.KRBClientInterceptor`` with the gokrb5 client\n5. Dial the GRPC connection with the ``WithUnaryInterceptor`` and ``WithStreamInterceptor`` DialOptions set.\n\n```go\nimport (\n    \"github.com/jcmturner/gokrb5/v8/client\"\n    \"github.com/jcmturner/gokrb5/v8/config\"\n    \"github.com/jcmturner/gokrb5/v8/keytab\"\n)\n\nkcfg, _ := config.Load(\"path/to/krb5.conf\")\nkt, _ := keytab.Load(\"path/to/keytab/file\")\ncl := client.NewWithKeytab(username, \"MY.REALM\", kt, kcfg)\n\nci := \u0026KRBClientInterceptor{\n    KRBClient: cl,\n}\n\nopts := []grpc.DialOption{\n\tgrpc.WithUnaryInterceptor(ci.Unary()),\n\tgrpc.WithStreamInterceptor(ci.Stream())}\n\nconn, _ := grpc.Dial(addr, opts...)\n```\n\n### Service Principal Name\nIn Kerberos authentication the client must request a ticket from the KDC for the service it wants to access.\nThe Service Principal Name (SPN) is what specifies this service.\nThe server side must have a keytab which contains the key for this SPN.\nThe SPN the client requests tickets for is derived in a number of ways:\n\n* If nothing is configured the SPN used will default to ``GRPC/\u003chostname\u003e``\n  where ``hostname`` is the host portion of the address passed to the ``grpc.Dial`` function.\n    \n* This SPN can be overridden by setting the value of the ``DefaultSPN`` field on the ``grpckrb.KRBClientInterceptor`` object:\n    ```go\n    ci := \u0026KRBClientInterceptor{\n        KRBClient: cl,\n        DefaultSPN: \"HOST/host.example.com\",\n    }\n    ```\n* SPNs can be defined per GRPC method call using the map in the ``MethodSPNs`` field of the ``grpckrb.KRBClientInterceptor`` object:\n    ```go\n    spns := make(map[string]string)\n    spns[\"/Service/Reflector\"] = \"HOST/host-a.example.com\"\n    spns[\"/Service/Mirror\"] = \"HOST/host-b.example.com\"\n    ci := \u0026KRBClientInterceptor{\n        KRBClient: cl,\n        MethodSPNs: spns,\n    }\n    ```\n  Any method not in this map will fall back to using the DefaultSPN.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcmturner%2Fgrpckrb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjcmturner%2Fgrpckrb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcmturner%2Fgrpckrb/lists"}