Skip to content

feat: basic implementation of secrets feature [DO NOT MERGE] #18775

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 34 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
88d5eec
feat: basic implementation of secrets feature
evgeniy-scherbina Jul 7, 2025
8fdc61b
test: fix migration tests
evgeniy-scherbina Jul 8, 2025
c6249d3
test: fix rbac tests
evgeniy-scherbina Jul 8, 2025
17326fd
Merge remote-tracking branch 'origin/main' into yevhenii/secrets-prot…
evgeniy-scherbina Jul 8, 2025
b5c904a
feat: add get-user-secret db query
evgeniy-scherbina Jul 8, 2025
122387f
feat: add list-user-secrets db query
evgeniy-scherbina Jul 8, 2025
147b22d
test: fix CI and dbmem
evgeniy-scherbina Jul 8, 2025
dc046ae
temporary commit
evgeniy-scherbina Jul 14, 2025
78bfa24
feat: implement API for creating & listing secrets
evgeniy-scherbina Jul 14, 2025
e416afe
Merge remote-tracking branch 'origin/main' into yevhenii/secrets-prot…
evgeniy-scherbina Jul 14, 2025
887f914
fix: delete dbmem after merge
evgeniy-scherbina Jul 14, 2025
991db6d
Merge remote-tracking branch 'origin/main' into yevhenii/secrets-prot…
evgeniy-scherbina Jul 15, 2025
6db3754
fix: migration numbers
evgeniy-scherbina Jul 15, 2025
f0c3a5e
ci: fix doc tests
evgeniy-scherbina Jul 15, 2025
137fb71
ci: fix doc tests
evgeniy-scherbina Jul 15, 2025
b580b5d
test: add TestUserSecrets test
evgeniy-scherbina Jul 15, 2025
b40ec25
test: improve TestUserSecrets test
evgeniy-scherbina Jul 15, 2025
ac8b0b6
refactor: add comments
evgeniy-scherbina Jul 15, 2025
b8712a6
feat: implement create command
evgeniy-scherbina Jul 16, 2025
1a716d2
feat: implement list command
evgeniy-scherbina Jul 16, 2025
e739809
feat: implement get command
evgeniy-scherbina Jul 16, 2025
e288818
feat: implement get --with-value command
evgeniy-scherbina Jul 16, 2025
dd2883e
make gen/golden-files
evgeniy-scherbina Jul 16, 2025
91b16de
ci: fix ci
evgeniy-scherbina Jul 17, 2025
39b0e41
feat: add params for auto-injection
evgeniy-scherbina Jul 21, 2025
a3d167e
feat: update creation of manifest
evgeniy-scherbina Jul 23, 2025
a73a4c5
fix: run make gen/golden-files
evgeniy-scherbina Jul 23, 2025
a1ee752
fix: run make gen
evgeniy-scherbina Jul 23, 2025
27de2ce
feat: pass secrets to agent via Manifest
evgeniy-scherbina Jul 23, 2025
57044e3
fix: merge with master
evgeniy-scherbina Jul 23, 2025
9fe247c
temporary workaround to pass tests
evgeniy-scherbina Jul 24, 2025
09449f1
Merge remote-tracking branch 'origin/main' into yevhenii/secrets-prot…
evgeniy-scherbina Jul 30, 2025
f1e05b5
Fixes after merge
evgeniy-scherbina Jul 30, 2025
1736849
Fix migrations
evgeniy-scherbina Jul 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: pass secrets to agent via Manifest
  • Loading branch information
evgeniy-scherbina committed Jul 23, 2025
commit 27de2ce76c39160f53e1c1cddc9828d89c76c849
4 changes: 4 additions & 0 deletions agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -1410,6 +1410,10 @@ func (a *agent) updateCommandEnv(current []string) (updated []string, err error)
}
envs["PATH"] = fmt.Sprintf("%s%c%s", a.scriptRunner.ScriptBinDir(), filepath.ListSeparator, envs["PATH"])

for _, secret := range manifest.UserSecrets {
envs[secret.EnvName] = secret.Value
}

for k, v := range envs {
updated = append(updated, fmt.Sprintf("%s=%s", k, v))
}
Expand Down
1,423 changes: 712 additions & 711 deletions agent/proto/agent.pb.go

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion agent/proto/agent.proto
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,14 @@ message Manifest {
repeated WorkspaceAgentMetadata.Description metadata = 12;
repeated WorkspaceAgentDevcontainer devcontainers = 17;

map<string,Secret> user_secrets = 19;
repeated Secret user_secrets = 19;
}

message Secret {
string name = 1;
string env_name = 2;
string file_path = 3;
string value = 4;
}

message WorkspaceAgentDevcontainer {
Expand Down
11 changes: 7 additions & 4 deletions coderd/agentapi/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ func (a *ManifestAPI) GetManifest(ctx context.Context, _ *agentproto.GetManifest
return nil, xerrors.Errorf("fetching workspace agent data: %w", err)
}

_ = userSecrets

appSlug := appurl.ApplicationURL{
AppSlugOrPort: "{{port}}",
AgentName: workspaceAgent.Name,
Expand Down Expand Up @@ -153,13 +155,14 @@ func (a *ManifestAPI) GetManifest(ctx context.Context, _ *agentproto.GetManifest
}, nil
}

func dbUserSecretsToProto(userSecrets []database.UserSecret) map[string]*agentproto.Secret {
userSecretsProto := make(map[string]*agentproto.Secret)
for _, userSecret := range userSecrets {
userSecretsProto[userSecret.Name] = &agentproto.Secret{
func dbUserSecretsToProto(userSecrets []database.UserSecret) []*agentproto.Secret {
userSecretsProto := make([]*agentproto.Secret, 0)
for i, userSecret := range userSecrets {
userSecretsProto[i] = &agentproto.Secret{
Name: userSecret.Name,
EnvName: userSecret.EnvName,
FilePath: userSecret.FilePath,
Value: userSecret.Value,
}
}

Expand Down
1 change: 1 addition & 0 deletions codersdk/agentsdk/agentsdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ type Manifest struct {
Metadata []codersdk.WorkspaceAgentMetadataDescription `json:"metadata"`
Scripts []codersdk.WorkspaceAgentScript `json:"scripts"`
Devcontainers []codersdk.WorkspaceAgentDevcontainer `json:"devcontainers"`
UserSecrets []codersdk.UserSecretWithValue `json:"user_secrets"`
}

type LogSource struct {
Expand Down
27 changes: 27 additions & 0 deletions codersdk/agentsdk/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ func ManifestFromProto(manifest *proto.Manifest) (Manifest, error) {
if err != nil {
return Manifest{}, xerrors.Errorf("error converting workspace agent devcontainers: %w", err)
}
userSecrets, err := SecretsFromProto(manifest.UserSecrets)
if err != nil {
return Manifest{}, xerrors.Errorf("error converting workspace agent devcontainers: %w", err)
}

return Manifest{
ParentID: parentID,
AgentID: agentID,
Expand All @@ -62,6 +67,7 @@ func ManifestFromProto(manifest *proto.Manifest) (Manifest, error) {
DisableDirectConnections: manifest.DisableDirectConnections,
Metadata: MetadataDescriptionsFromProto(manifest.Metadata),
Devcontainers: devcontainers,
UserSecrets: userSecrets,
}, nil
}

Expand Down Expand Up @@ -449,3 +455,24 @@ func ProtoFromDevcontainer(dc codersdk.WorkspaceAgentDevcontainer) *proto.Worksp
ConfigPath: dc.ConfigPath,
}
}

func SecretsFromProto(pss []*proto.Secret) ([]codersdk.UserSecretWithValue, error) {
ret := make([]codersdk.UserSecretWithValue, len(pss))
for i, ps := range pss {
secret, err := SecretFromProto(ps)
if err != nil {
return nil, xerrors.Errorf("parse secret %v: %w", i, err)
}
ret[i] = secret
}
return ret, nil
}

func SecretFromProto(ps *proto.Secret) (codersdk.UserSecretWithValue, error) {
return codersdk.UserSecretWithValue{
Name: ps.Name,
EnvName: ps.EnvName,
FilePath: ps.FilePath,
Value: ps.Value,
}, nil
}
12 changes: 12 additions & 0 deletions codersdk/user_secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ type UserSecret struct {
UpdatedAt time.Time `json:"updated_at" format:"date-time"`
}

type UserSecretWithValue struct {
ID uuid.UUID `json:"id" format:"uuid"`
UserID uuid.UUID `json:"user_id" format:"uuid"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
EnvName string `json:"env_name,omitempty"`
FilePath string `json:"file_path,omitempty"`
Value string `json:"value"`
CreatedAt time.Time `json:"created_at" format:"date-time"`
UpdatedAt time.Time `json:"updated_at" format:"date-time"`
}

type UserSecretValue struct {
Value string `json:"value"`
}
Expand Down
13 changes: 13 additions & 0 deletions site/src/api/typesGenerated.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy