Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
forked fromcoder/coder

Commit45160c7

Browse files
authored
feat: add schema for key rotation (coder#14662)
1 parent45420b9 commit45160c7

29 files changed

+977
-2
lines changed

‎coderd/apidoc/docs.go‎

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/apidoc/swagger.json‎

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/dbauthz/dbauthz.go‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ var (
253253
rbac.ResourceDeploymentConfig.Type: {policy.ActionCreate,policy.ActionUpdate,policy.ActionDelete},
254254
rbac.ResourceNotificationPreference.Type: {policy.ActionCreate,policy.ActionUpdate,policy.ActionDelete},
255255
rbac.ResourceNotificationTemplate.Type: {policy.ActionCreate,policy.ActionUpdate,policy.ActionDelete},
256+
rbac.ResourceCryptoKey.Type: {policy.ActionCreate,policy.ActionUpdate,policy.ActionDelete},
256257
}),
257258
Org:map[string][]rbac.Permission{},
258259
User: []rbac.Permission{},
@@ -1041,6 +1042,13 @@ func (q *querier) DeleteCoordinator(ctx context.Context, id uuid.UUID) error {
10411042
returnq.db.DeleteCoordinator(ctx,id)
10421043
}
10431044

1045+
func (q*querier)DeleteCryptoKey(ctx context.Context,arg database.DeleteCryptoKeyParams) (database.CryptoKey,error) {
1046+
iferr:=q.authorizeContext(ctx,policy.ActionDelete,rbac.ResourceCryptoKey);err!=nil {
1047+
return database.CryptoKey{},err
1048+
}
1049+
returnq.db.DeleteCryptoKey(ctx,arg)
1050+
}
1051+
10441052
func (q*querier)DeleteCustomRole(ctx context.Context,arg database.DeleteCustomRoleParams)error {
10451053
ifarg.OrganizationID.UUID!=uuid.Nil {
10461054
iferr:=q.authorizeContext(ctx,policy.ActionDelete,rbac.ResourceAssignOrgRole.InOrg(arg.OrganizationID.UUID));err!=nil {
@@ -1383,6 +1391,20 @@ func (q *querier) GetCoordinatorResumeTokenSigningKey(ctx context.Context) (stri
13831391
returnq.db.GetCoordinatorResumeTokenSigningKey(ctx)
13841392
}
13851393

1394+
func (q*querier)GetCryptoKeyByFeatureAndSequence(ctx context.Context,arg database.GetCryptoKeyByFeatureAndSequenceParams) (database.CryptoKey,error) {
1395+
iferr:=q.authorizeContext(ctx,policy.ActionRead,rbac.ResourceCryptoKey);err!=nil {
1396+
return database.CryptoKey{},err
1397+
}
1398+
returnq.db.GetCryptoKeyByFeatureAndSequence(ctx,arg)
1399+
}
1400+
1401+
func (q*querier)GetCryptoKeys(ctx context.Context) ([]database.CryptoKey,error) {
1402+
iferr:=q.authorizeContext(ctx,policy.ActionRead,rbac.ResourceCryptoKey);err!=nil {
1403+
returnnil,err
1404+
}
1405+
returnq.db.GetCryptoKeys(ctx)
1406+
}
1407+
13861408
func (q*querier)GetDBCryptKeys(ctx context.Context) ([]database.DBCryptKey,error) {
13871409
iferr:=q.authorizeContext(ctx,policy.ActionRead,rbac.ResourceSystem);err!=nil {
13881410
returnnil,err
@@ -1549,6 +1571,13 @@ func (q *querier) GetLastUpdateCheck(ctx context.Context) (string, error) {
15491571
returnq.db.GetLastUpdateCheck(ctx)
15501572
}
15511573

1574+
func (q*querier)GetLatestCryptoKeyByFeature(ctx context.Context,feature database.CryptoKeyFeature) (database.CryptoKey,error) {
1575+
iferr:=q.authorizeContext(ctx,policy.ActionRead,rbac.ResourceCryptoKey);err!=nil {
1576+
return database.CryptoKey{},err
1577+
}
1578+
returnq.db.GetLatestCryptoKeyByFeature(ctx,feature)
1579+
}
1580+
15521581
func (q*querier)GetLatestWorkspaceBuildByWorkspaceID(ctx context.Context,workspaceID uuid.UUID) (database.WorkspaceBuild,error) {
15531582
if_,err:=q.GetWorkspaceByID(ctx,workspaceID);err!=nil {
15541583
return database.WorkspaceBuild{},err
@@ -2662,6 +2691,13 @@ func (q *querier) InsertAuditLog(ctx context.Context, arg database.InsertAuditLo
26622691
returninsert(q.log,q.auth,rbac.ResourceAuditLog,q.db.InsertAuditLog)(ctx,arg)
26632692
}
26642693

2694+
func (q*querier)InsertCryptoKey(ctx context.Context,arg database.InsertCryptoKeyParams) (database.CryptoKey,error) {
2695+
iferr:=q.authorizeContext(ctx,policy.ActionCreate,rbac.ResourceCryptoKey);err!=nil {
2696+
return database.CryptoKey{},err
2697+
}
2698+
returnq.db.InsertCryptoKey(ctx,arg)
2699+
}
2700+
26652701
func (q*querier)InsertCustomRole(ctx context.Context,arg database.InsertCustomRoleParams) (database.CustomRole,error) {
26662702
// Org and site role upsert share the same query. So switch the assertion based on the org uuid.
26672703
ifarg.OrganizationID.UUID!=uuid.Nil {
@@ -3169,6 +3205,13 @@ func (q *querier) UpdateAPIKeyByID(ctx context.Context, arg database.UpdateAPIKe
31693205
returnupdate(q.log,q.auth,fetch,q.db.UpdateAPIKeyByID)(ctx,arg)
31703206
}
31713207

3208+
func (q*querier)UpdateCryptoKeyDeletesAt(ctx context.Context,arg database.UpdateCryptoKeyDeletesAtParams) (database.CryptoKey,error) {
3209+
iferr:=q.authorizeContext(ctx,policy.ActionUpdate,rbac.ResourceCryptoKey);err!=nil {
3210+
return database.CryptoKey{},err
3211+
}
3212+
returnq.db.UpdateCryptoKeyDeletesAt(ctx,arg)
3213+
}
3214+
31723215
func (q*querier)UpdateCustomRole(ctx context.Context,arg database.UpdateCustomRoleParams) (database.CustomRole,error) {
31733216
ifarg.OrganizationID.UUID!=uuid.Nil {
31743217
iferr:=q.authorizeContext(ctx,policy.ActionUpdate,rbac.ResourceAssignOrgRole.InOrg(arg.OrganizationID.UUID));err!=nil {

‎coderd/database/dbauthz/dbauthz_test.go‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2253,6 +2253,57 @@ func (s *MethodTestSuite) TestDBCrypt() {
22532253
}))
22542254
}
22552255

2256+
func (s*MethodTestSuite)TestCryptoKeys() {
2257+
s.Run("GetCryptoKeys",s.Subtest(func(db database.Store,check*expects) {
2258+
check.Args().
2259+
Asserts(rbac.ResourceCryptoKey,policy.ActionRead)
2260+
}))
2261+
s.Run("InsertCryptoKey",s.Subtest(func(db database.Store,check*expects) {
2262+
check.Args(database.InsertCryptoKeyParams{
2263+
Feature:database.CryptoKeyFeatureWorkspaceApps,
2264+
}).
2265+
Asserts(rbac.ResourceCryptoKey,policy.ActionCreate)
2266+
}))
2267+
s.Run("DeleteCryptoKey",s.Subtest(func(db database.Store,check*expects) {
2268+
key:=dbgen.CryptoKey(s.T(),db, database.CryptoKey{
2269+
Feature:database.CryptoKeyFeatureWorkspaceApps,
2270+
Sequence:4,
2271+
})
2272+
check.Args(database.DeleteCryptoKeyParams{
2273+
Feature:key.Feature,
2274+
Sequence:key.Sequence,
2275+
}).Asserts(rbac.ResourceCryptoKey,policy.ActionDelete)
2276+
}))
2277+
s.Run("GetCryptoKeyByFeatureAndSequence",s.Subtest(func(db database.Store,check*expects) {
2278+
key:=dbgen.CryptoKey(s.T(),db, database.CryptoKey{
2279+
Feature:database.CryptoKeyFeatureWorkspaceApps,
2280+
Sequence:4,
2281+
})
2282+
check.Args(database.GetCryptoKeyByFeatureAndSequenceParams{
2283+
Feature:key.Feature,
2284+
Sequence:key.Sequence,
2285+
}).Asserts(rbac.ResourceCryptoKey,policy.ActionRead).Returns(key)
2286+
}))
2287+
s.Run("GetLatestCryptoKeyByFeature",s.Subtest(func(db database.Store,check*expects) {
2288+
dbgen.CryptoKey(s.T(),db, database.CryptoKey{
2289+
Feature:database.CryptoKeyFeatureWorkspaceApps,
2290+
Sequence:4,
2291+
})
2292+
check.Args(database.CryptoKeyFeatureWorkspaceApps).Asserts(rbac.ResourceCryptoKey,policy.ActionRead)
2293+
}))
2294+
s.Run("UpdateCryptoKeyDeletesAt",s.Subtest(func(db database.Store,check*expects) {
2295+
key:=dbgen.CryptoKey(s.T(),db, database.CryptoKey{
2296+
Feature:database.CryptoKeyFeatureWorkspaceApps,
2297+
Sequence:4,
2298+
})
2299+
check.Args(database.UpdateCryptoKeyDeletesAtParams{
2300+
Feature:key.Feature,
2301+
Sequence:key.Sequence,
2302+
DeletesAt: sql.NullTime{Time:time.Now(),Valid:true},
2303+
}).Asserts(rbac.ResourceCryptoKey,policy.ActionUpdate)
2304+
}))
2305+
}
2306+
22562307
func (s*MethodTestSuite)TestSystemFunctions() {
22572308
s.Run("UpdateUserLinkedID",s.Subtest(func(db database.Store,check*expects) {
22582309
u:=dbgen.User(s.T(),db, database.User{})

‎coderd/database/dbgen/dbgen.go‎

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package dbgen
22

33
import (
44
"context"
5+
"crypto/rand"
56
"crypto/sha256"
67
"database/sql"
78
"encoding/hex"
@@ -16,6 +17,7 @@ import (
1617
"github.com/google/uuid"
1718
"github.com/sqlc-dev/pqtype"
1819
"github.com/stretchr/testify/require"
20+
"golang.org/x/xerrors"
1921

2022
"github.com/coder/coder/v2/coderd/database"
2123
"github.com/coder/coder/v2/coderd/database/dbauthz"
@@ -893,6 +895,40 @@ func CustomRole(t testing.TB, db database.Store, seed database.CustomRole) datab
893895
returnrole
894896
}
895897

898+
funcCryptoKey(t testing.TB,db database.Store,seed database.CryptoKey) database.CryptoKey {
899+
t.Helper()
900+
901+
seed.Feature=takeFirst(seed.Feature,database.CryptoKeyFeatureWorkspaceApps)
902+
903+
if!seed.Secret.Valid {
904+
secret,err:=newCryptoKeySecret(seed.Feature)
905+
require.NoError(t,err,"generate secret")
906+
seed.Secret= sql.NullString{
907+
String:secret,
908+
Valid:true,
909+
}
910+
}
911+
912+
key,err:=db.InsertCryptoKey(genCtx, database.InsertCryptoKeyParams{
913+
Sequence:takeFirst(seed.Sequence,123),
914+
Secret:seed.Secret,
915+
SecretKeyID:takeFirst(seed.SecretKeyID, sql.NullString{}),
916+
Feature:seed.Feature,
917+
StartsAt:takeFirst(seed.StartsAt,time.Now()),
918+
})
919+
require.NoError(t,err,"insert crypto key")
920+
921+
ifseed.DeletesAt.Valid {
922+
key,err=db.UpdateCryptoKeyDeletesAt(genCtx, database.UpdateCryptoKeyDeletesAtParams{
923+
Feature:key.Feature,
924+
Sequence:key.Sequence,
925+
DeletesAt: sql.NullTime{Time:seed.DeletesAt.Time,Valid:true},
926+
})
927+
require.NoError(t,err,"update crypto key deletes_at")
928+
}
929+
returnkey
930+
}
931+
896932
funcProvisionerJobTimings(t testing.TB,db database.Store,seed database.InsertProvisionerJobTimingsParams) []database.ProvisionerJobTiming {
897933
timings,err:=db.InsertProvisionerJobTimings(genCtx,seed)
898934
require.NoError(t,err,"insert provisioner job timings")
@@ -942,3 +978,24 @@ func takeFirst[Value comparable](values ...Value) Value {
942978
returnv!=empty
943979
})
944980
}
981+
982+
funcnewCryptoKeySecret(feature database.CryptoKeyFeature) (string,error) {
983+
switchfeature {
984+
casedatabase.CryptoKeyFeatureWorkspaceApps:
985+
returngenerateCryptoKey(96)
986+
casedatabase.CryptoKeyFeatureOidcConvert:
987+
returngenerateCryptoKey(32)
988+
casedatabase.CryptoKeyFeatureTailnetResume:
989+
returngenerateCryptoKey(64)
990+
}
991+
return"",xerrors.Errorf("unknown feature: %s",feature)
992+
}
993+
994+
funcgenerateCryptoKey(lengthint) (string,error) {
995+
b:=make([]byte,length)
996+
_,err:=rand.Read(b)
997+
iferr!=nil {
998+
return"",xerrors.Errorf("rand read: %w",err)
999+
}
1000+
returnhex.EncodeToString(b),nil
1001+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp