@@ -56,7 +56,7 @@ const (
56
56
57
57
type Options struct {
58
58
Filesystem afero.Fs
59
- ExchangeToken func (ctx context.Context ) error
59
+ ExchangeToken func (ctx context.Context ) ( string , error )
60
60
Client Client
61
61
ReconnectingPTYTimeout time.Duration
62
62
EnvironmentVariables map [string ]string
@@ -78,6 +78,11 @@ func New(options Options) io.Closer {
78
78
if options .Filesystem == nil {
79
79
options .Filesystem = afero .NewOsFs ()
80
80
}
81
+ if options .ExchangeToken == nil {
82
+ options .ExchangeToken = func (ctx context.Context ) (string , error ) {
83
+ return "" , nil
84
+ }
85
+ }
81
86
ctx , cancelFunc := context .WithCancel (context .Background ())
82
87
server := & agent {
83
88
reconnectingPTYTimeout : options .ReconnectingPTYTimeout ,
@@ -97,7 +102,7 @@ func New(options Options) io.Closer {
97
102
type agent struct {
98
103
logger slog.Logger
99
104
client Client
100
- exchangeToken func (ctx context.Context ) error
105
+ exchangeToken func (ctx context.Context ) ( string , error )
101
106
filesystem afero.Fs
102
107
103
108
reconnectingPTYs sync.Map
@@ -110,8 +115,9 @@ type agent struct {
110
115
111
116
envVars map [string ]string
112
117
// metadata is atomic because values can change after reconnection.
113
- metadata atomic.Value
114
- sshServer * ssh.Server
118
+ metadata atomic.Value
119
+ sessionToken atomic.Pointer [string ]
120
+ sshServer * ssh.Server
115
121
116
122
network * tailnet.Conn
117
123
stats * Stats
@@ -147,14 +153,13 @@ func (a *agent) run(ctx context.Context) error {
147
153
// This allows the agent to refresh it's token if necessary.
148
154
// For instance identity this is required, since the instance
149
155
// may not have re-provisioned, but a new agent ID was created.
150
- if a .exchangeToken != nil {
151
- err := a .exchangeToken (ctx )
152
- if err != nil {
153
- return xerrors .Errorf ("exchange token: %w" , err )
154
- }
156
+ sessionToken , err := a .exchangeToken (ctx )
157
+ if err != nil {
158
+ return xerrors .Errorf ("exchange token: %w" , err )
155
159
}
160
+ a .sessionToken .Store (& sessionToken )
156
161
157
- err : = a .client .PostWorkspaceAgentVersion (ctx , buildinfo .Version ())
162
+ err = a .client .PostWorkspaceAgentVersion (ctx , buildinfo .Version ())
158
163
if err != nil {
159
164
return xerrors .Errorf ("update workspace agent version: %w" , err )
160
165
}
@@ -571,6 +576,9 @@ func (a *agent) createCommand(ctx context.Context, rawCommand string, env []stri
571
576
unixExecutablePath := strings .ReplaceAll (executablePath , "\\ " , "/" )
572
577
cmd .Env = append (cmd .Env , fmt .Sprintf (`GIT_SSH_COMMAND=%s gitssh --` , unixExecutablePath ))
573
578
579
+ // Specific Coder subcommands require the agent token exposed!
580
+ cmd .Env = append (cmd .Env , fmt .Sprintf ("CODER_AGENT_TOKEN=%s" , * a .sessionToken .Load ()))
581
+
574
582
// Set SSH connection environment variables (these are also set by OpenSSH
575
583
// and thus expected to be present by SSH clients). Since the agent does
576
584
// networking in-memory, trying to provide accurate values here would be
0 commit comments