feat: enable key rotation (#15066)

This PR contains the remaining logic necessary to hook up key rotation
to the product.
This commit is contained in:
Jon Ayers
2024-10-25 17:14:35 +01:00
committed by GitHub
parent ccfffc6911
commit cd890aa3a0
54 changed files with 1412 additions and 1129 deletions

View File

@ -13,6 +13,7 @@ import (
"testing"
"time"
"github.com/go-jose/go-jose/v4/jwt"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -20,6 +21,7 @@ import (
"github.com/coder/coder/v2/agent/agenttest"
"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/coderd/jwtutils"
"github.com/coder/coder/v2/coderd/workspaceapps"
"github.com/coder/coder/v2/coderd/workspaceapps/appurl"
"github.com/coder/coder/v2/codersdk"
@ -94,8 +96,7 @@ func Test_ResolveRequest(t *testing.T) {
_ = closer.Close()
})
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium)
t.Cleanup(cancel)
ctx := testutil.Context(t, testutil.WaitMedium)
firstUser := coderdtest.CreateFirstUser(t, client)
me, err := client.User(ctx, codersdk.Me)
@ -276,15 +277,17 @@ func Test_ResolveRequest(t *testing.T) {
_ = w.Body.Close()
require.Equal(t, &workspaceapps.SignedToken{
RegisteredClaims: jwtutils.RegisteredClaims{
Expiry: jwt.NewNumericDate(token.Expiry.Time()),
},
Request: req,
Expiry: token.Expiry, // ignored to avoid flakiness
UserID: me.ID,
WorkspaceID: workspace.ID,
AgentID: agentID,
AppURL: appURL,
}, token)
require.NotZero(t, token.Expiry)
require.WithinDuration(t, time.Now().Add(workspaceapps.DefaultTokenExpiry), token.Expiry, time.Minute)
require.WithinDuration(t, time.Now().Add(workspaceapps.DefaultTokenExpiry), token.Expiry.Time(), time.Minute)
// Check that the token was set in the response and is valid.
require.Len(t, w.Cookies(), 1)
@ -292,10 +295,11 @@ func Test_ResolveRequest(t *testing.T) {
require.Equal(t, codersdk.SignedAppTokenCookie, cookie.Name)
require.Equal(t, req.BasePath, cookie.Path)
parsedToken, err := api.AppSecurityKey.VerifySignedToken(cookie.Value)
var parsedToken workspaceapps.SignedToken
err := jwtutils.Verify(ctx, api.AppSigningKeyCache, cookie.Value, &parsedToken)
require.NoError(t, err)
// normalize expiry
require.WithinDuration(t, token.Expiry, parsedToken.Expiry, 2*time.Second)
require.WithinDuration(t, token.Expiry.Time(), parsedToken.Expiry.Time(), 2*time.Second)
parsedToken.Expiry = token.Expiry
require.Equal(t, token, &parsedToken)
@ -314,7 +318,7 @@ func Test_ResolveRequest(t *testing.T) {
})
require.True(t, ok)
// normalize expiry
require.WithinDuration(t, token.Expiry, secondToken.Expiry, 2*time.Second)
require.WithinDuration(t, token.Expiry.Time(), secondToken.Expiry.Time(), 2*time.Second)
secondToken.Expiry = token.Expiry
require.Equal(t, token, secondToken)
}
@ -540,13 +544,16 @@ func Test_ResolveRequest(t *testing.T) {
// App name differs
AppSlugOrPort: appNamePublic,
}).Normalize(),
Expiry: time.Now().Add(time.Minute),
RegisteredClaims: jwtutils.RegisteredClaims{
Expiry: jwt.NewNumericDate(time.Now().Add(time.Minute)),
},
UserID: me.ID,
WorkspaceID: workspace.ID,
AgentID: agentID,
AppURL: appURL,
}
badTokenStr, err := api.AppSecurityKey.SignToken(badToken)
badTokenStr, err := jwtutils.Sign(ctx, api.AppSigningKeyCache, badToken)
require.NoError(t, err)
req := (workspaceapps.Request{
@ -589,7 +596,8 @@ func Test_ResolveRequest(t *testing.T) {
require.Len(t, cookies, 1)
require.Equal(t, cookies[0].Name, codersdk.SignedAppTokenCookie)
require.NotEqual(t, cookies[0].Value, badTokenStr)
parsedToken, err := api.AppSecurityKey.VerifySignedToken(cookies[0].Value)
var parsedToken workspaceapps.SignedToken
err = jwtutils.Verify(ctx, api.AppSigningKeyCache, cookies[0].Value, &parsedToken)
require.NoError(t, err)
require.Equal(t, appNameOwner, parsedToken.AppSlugOrPort)
})