MCPcopy Create free account
hub / github.com/coder/coder / exchange

Method exchange

codersdk/agentsdk/aws.go:43–104  ·  view source on GitHub ↗

exchange uses the Amazon Metadata API to fetch a signed payload, and exchange it for a session token for a workspace agent. The requesting instance must be registered as a resource in the latest history for a workspace.

(ctx context.Context)

Source from the content-addressed store, hash-verified

41//
42// The requesting instance must be registered as a resource in the latest history for a workspace.
43func (a *AWSSessionTokenExchanger) exchange(ctx context.Context) (AuthenticateResponse, error) {
44 req, err := http.NewRequestWithContext(ctx, http.MethodPut, "http://169.254.169.254/latest/api/token", nil)
45 if err != nil {
46 return AuthenticateResponse{}, nil
47 }
48 req.Header.Set("X-aws-ec2-metadata-token-ttl-seconds", "21600")
49 res, err := a.client.HTTPClient.Do(req)
50 if err != nil {
51 return AuthenticateResponse{}, err
52 }
53 defer res.Body.Close()
54 token, err := io.ReadAll(res.Body)
55 if err != nil {
56 return AuthenticateResponse{}, xerrors.Errorf("read token: %w", err)
57 }
58
59 req, err = http.NewRequestWithContext(ctx, http.MethodGet, "http://169.254.169.254/latest/dynamic/instance-identity/signature", nil)
60 if err != nil {
61 return AuthenticateResponse{}, nil
62 }
63 req.Header.Set("X-aws-ec2-metadata-token", string(token))
64 res, err = a.client.HTTPClient.Do(req)
65 if err != nil {
66 return AuthenticateResponse{}, err
67 }
68 defer res.Body.Close()
69 signature, err := io.ReadAll(res.Body)
70 if err != nil {
71 return AuthenticateResponse{}, xerrors.Errorf("read token: %w", err)
72 }
73
74 req, err = http.NewRequestWithContext(ctx, http.MethodGet, "http://169.254.169.254/latest/dynamic/instance-identity/document", nil)
75 if err != nil {
76 return AuthenticateResponse{}, nil
77 }
78 req.Header.Set("X-aws-ec2-metadata-token", string(token))
79 res, err = a.client.HTTPClient.Do(req)
80 if err != nil {
81 return AuthenticateResponse{}, err
82 }
83 defer res.Body.Close()
84 document, err := io.ReadAll(res.Body)
85 if err != nil {
86 return AuthenticateResponse{}, xerrors.Errorf("read token: %w", err)
87 }
88
89 // request without the token to avoid re-entering this function
90 res, err = a.client.RequestWithoutSessionToken(ctx, http.MethodPost, "/api/v2/workspaceagents/aws-instance-identity", AWSInstanceIdentityToken{
91 Signature: string(signature),
92 Document: string(document),
93 AgentName: a.agentName,
94 })
95 if err != nil {
96 return AuthenticateResponse{}, err
97 }
98 defer res.Body.Close()
99 if res.StatusCode != http.StatusOK {
100 return AuthenticateResponse{}, codersdk.ReadBodyAsError(res)

Callers

nothing calls this directly

Calls 7

ReadBodyAsErrorFunction · 0.92
SetMethod · 0.65
DoMethod · 0.65
CloseMethod · 0.65
ReadAllMethod · 0.45
ErrorfMethod · 0.45

Tested by

no test coverage detected