• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

.github/H21-May-2021-9773

jwt/H21-May-2021-2,2841,944

oidc/H21-May-2021-11,5889,171

util/H21-May-2021-5243

CHANGELOG.mdH A D21-May-2021221 94

CONTRIBUTING.mdH A D21-May-20213.1 KiB8558

LICENSEH A D21-May-202115.5 KiB363265

README.mdH A D21-May-20215.6 KiB181148

docs.goH A D21-May-2021197 61

docs_test.goH A D21-May-20212 KiB8052

go.modH A D21-May-20211.1 KiB2926

go.sumH A D21-May-20217.6 KiB8382

README.md

1# cap
2
3`cap` (collection of authentication packages) provides a collection of related
4packages which enable support for OIDC, JWT Verification and Distributed Claims.
5
6**Please note**: We take security and our users' trust very seriously. If you
7believe you have found a security issue, please [responsibly
8disclose](https://www.hashicorp.com/security#vulnerability-reporting) by
9contacting us at  security@hashicorp.com.
10
11## Contributing
12
13Thank you for your interest in contributing! Please refer to
14[CONTRIBUTING.md](https://github.com/hashicorp/cap/blob/main/CONTRIBUTING.md)
15for guidance.
16
17<hr>
18
19### [`oidc package`](./oidc)
20[![Go Reference](https://pkg.go.dev/badge/github.com/hashicorp/cap/oidc.svg)](https://pkg.go.dev/github.com/hashicorp/cap/oidc)
21
22 A package for writing clients that integrate with OIDC Providers. Primary types provided by the
23 package are:
24 1. Request
25 2. Token
26 3. Config
27 4. Provider
28
29The package also provides callbacks (in the form of http.HandlerFunc) for
30handling OIDC provider responses to authorization code flow (with optional PKCE)
31and implicit flow authentication attempts.
32<hr>
33
34Example of a provider using an authorization code flow:
35```go
36// Create a new provider config
37pc, err := oidc.NewConfig(
38    "http://your-issuer.com/",
39    "your_client_id",
40    "your_client_secret",
41    []oidc.Alg{oidc.RS256},
42    []string{"https://your_redirect_url"},
43)
44if err != nil {
45    // handle error
46}
47
48// Create a provider
49p, err := oidc.NewProvider(pc)
50if err != nil {
51    // handle error
52}
53defer p.Done()
54
55
56// Create a Request for a user's authorization code flow authentication attempt,
57// with a 2 min timeout for  completion.
58oidcRequest, err := oidc.NewRequest(2 * time.Minute, "https://your_redirect_url")
59if err != nil {
60    // handle error
61}
62
63
64// Create an auth URL
65authURL, err := p.AuthURL(ctx, oidcRequest)
66if err != nil {
67    // handle error
68}
69fmt.Println("open url to kick-off authentication: ", authURL)
70```
71
72Create a http.Handler for OIDC authentication response redirects.
73```go
74func NewHandler(ctx context.Context, p *oidc.Provider, r callback.RequestReader) (http.HandlerFunc, error)
75    if p == nil {
76        // handle error
77    }
78    if rw == nil {
79        // handle error
80    }
81    return func(w http.ResponseWriter, req *http.Request) {
82        oidcRequest, err := rw.Read(ctx, req.FormValue("state"))
83        if err != nil {
84            // handle error
85        }
86        // Exchange(...) will verify the tokens before returning.
87        token, err := p.Exchange(ctx, oidcRequest, req.FormValue("state"), req.FormValue("code"))
88        if err != nil {
89            // handle error
90        }
91        var claims map[string]interface{}
92        if err := token.IDToken().Claims(&claims); err != nil {
93            // handle error
94        }
95
96        // Get the user's claims via the provider's UserInfo endpoint
97        var infoClaims map[string]interface{}
98        err = p.UserInfo(ctx, token.StaticTokenSource(), claims["sub"].(string), &infoClaims)
99        if err != nil {
100            // handle error
101        }
102        resp := struct {
103		    IDTokenClaims  map[string]interface{}
104		    UserInfoClaims map[string]interface{}
105		}{claims, infoClaims}
106		enc := json.NewEncoder(w)
107		if err := enc.Encode(resp); err != nil {
108			// handle error
109        }
110    }
111}
112```
113
114### [`jwt package`](./jwt)
115[![Go Reference](https://pkg.go.dev/badge/github.com/hashicorp/cap/jwt.svg)](https://pkg.go.dev/github.com/hashicorp/cap/jwt)
116
117Package jwt provides signature verification and claims set validation for JSON Web Tokens (JWT)
118of the JSON Web Signature (JWS) form.
119
120JWT claims set validation provided by the package includes the option to validate
121all registered claim names defined in [rfc7519#section-4.1](https://tools.ietf.org/html/rfc7519#section-4.1).
122
123JOSE header validation provided by the the package includes the option to validate the "alg"
124(Algorithm) Header Parameter defined in [rfc7515#section-4.1](https://tools.ietf.org/html/rfc7515#section-4.1).
125
126JWT signature verification is supported by providing keys from the following sources:
127
128- JSON Web Key Set (JWKS) URL
129- OIDC Discovery mechanism
130- Local public keys
131
132JWT signature verification supports the following asymmetric algorithms defined in
133[rfc7518.html#section-3.1](https://www.rfc-editor.org/rfc/rfc7518.html#section-3.1):
134
135| Identifier     | Signing Algorithm |
136| -------------- | :---------------- |
137| RS256          | RSASSA-PKCS1-v1_5 using SHA-256 |
138| RS384          | RSASSA-PKCS1-v1_5 using SHA-384 |
139| RS512          | RSASSA-PKCS1-v1_5 using SHA-512 |
140| ES256          | ECDSA using P-256 and SHA-256 |
141| ES384          | ECDSA using P-384 and SHA-384 |
142| ES512          | ECDSA using P-521 and SHA-512 |
143| PS256          | RSASSA-PSS using SHA-256 and MGF1 with SHA-256 |
144| PS384          | RSASSA-PSS using SHA-384 and MGF1 with SHA-384 |
145| PS512          | RSASSA-PSS using SHA-512 and MGF1 with SHA-512 |
146| EdDSA          | Ed25519 using SHA-512 |
147
148<hr>
149
150Example usage of JWT signature verification and claims set validation using keys from a JWKS URL:
151
152```go
153ctx := context.Background()
154
155keySet, err := jwt.NewJSONWebKeySet(ctx, "your_jwks_url", "your_jwks_ca_pem")
156if err != nil {
157	log.Fatal(err)
158}
159
160validator, err := jwt.NewValidator(keySet)
161if err != nil {
162	log.Fatal(err)
163}
164
165expected := jwt.Expected{
166	Issuer:            "your_expected_issuer",
167	Subject:           "your_expected_subject",
168	ID:                "your_expected_jwt_id",
169	Audiences:         []string{"your_expected_audiences"},
170	SigningAlgorithms: []jwt.Alg{jwt.RS256},
171}
172
173token := "header.payload.signature"
174claims, err := validator.Validate(ctx, token, expected)
175if err != nil {
176	log.Fatal(err)
177}
178```
179
180For additional documentation and usage examples, see [jwt/README.md](./jwt).
181