-
Notifications
You must be signed in to change notification settings - Fork 2.7k
/
Copy pathImdsV2.ts
171 lines (152 loc) · 5.94 KB
/
ImdsV2.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
import { INetworkModule, Logger } from "@azure/msal-common/node";
// import { Agent } from "https";
import { ManagedIdentityId } from "../../config/ManagedIdentityId.js";
import { ManagedIdentityRequestParameters } from "../../config/ManagedIdentityRequestParameters.js";
import { BaseManagedIdentitySource } from "./BaseManagedIdentitySource.js";
import { CryptoProvider } from "../../crypto/CryptoProvider.js";
import {
API_VERSION_QUERY_PARAMETER_NAME,
CLIENT_REQUEST_ID_HEADER_NAME,
HttpMethod,
METADATA_HEADER_NAME,
ManagedIdentityIdType,
RESOURCE_BODY_OR_QUERY_PARAMETER_NAME,
} from "../../utils/Constants.js";
import { NodeStorage } from "../../cache/NodeStorage.js";
import { Imds, IMDS_API_VERSION } from "./Imds.js";
import { ShortLivedCredential } from "../../response/ShortLivedCredentialResponse.js";
const CREDENTIAL_PATH: string =
"/metadata/identity/credential?cred-api-version=1.0";
export class ImdsV2 extends BaseManagedIdentitySource {
private identityEndpoint: string;
constructor(
logger: Logger,
nodeStorage: NodeStorage,
networkClient: INetworkModule,
cryptoProvider: CryptoProvider,
identityEndpoint: string
) {
super(logger, nodeStorage, networkClient, cryptoProvider);
this.identityEndpoint = identityEndpoint;
}
public static tryCreate(
logger: Logger,
nodeStorage: NodeStorage,
networkClient: INetworkModule,
cryptoProvider: CryptoProvider
): ImdsV2 | null {
if (!this.isCredentialEndpointAvailable()) {
return null;
}
const validatedIdentityEndpoint: string =
Imds.getValidatedIdentityEndpoint(CREDENTIAL_PATH, logger);
return new ImdsV2(
logger,
nodeStorage,
networkClient,
cryptoProvider,
validatedIdentityEndpoint
);
}
public static isCredentialEndpointAvailable(): boolean {
// TODO: Probe credential endpoint. If it doesn't return 200, return null
return true;
}
public createRequest(
resource: string,
managedIdentityId: ManagedIdentityId
): ManagedIdentityRequestParameters {
const imdsRequest: ManagedIdentityRequestParameters =
new ManagedIdentityRequestParameters(
HttpMethod.POST,
this.identityEndpoint
);
imdsRequest.headers[METADATA_HEADER_NAME] = "true";
imdsRequest.headers[CLIENT_REQUEST_ID_HEADER_NAME] = "1234567890"; // TODO: generate random request ID
imdsRequest.queryParameters[API_VERSION_QUERY_PARAMETER_NAME] =
IMDS_API_VERSION;
imdsRequest.queryParameters[RESOURCE_BODY_OR_QUERY_PARAMETER_NAME] =
resource;
if (
managedIdentityId.idType !== ManagedIdentityIdType.SYSTEM_ASSIGNED
) {
imdsRequest.queryParameters[
this.getManagedIdentityUserAssignedIdQueryParameterKey(
managedIdentityId.idType,
true // indicates source is IMDS
)
] = managedIdentityId.id;
}
/*
* TODO: add self-signed mTLS certificate functionality
* If Windows, check certificate store for mTLS certificate (no Linux support)
* Otherwise, check in-memory cache for mTLS certificate
* If not either of the above, create self-signed mTLS certificate
*/
/*
* const mTLSCertificatePem: string = "fake_cert";
* const privateKeyPem: string = "fake_private_key";
*/
const sha256HashOfPublicKey: string = "fake_sha256_hash_of_public_key";
const x5C: string = "fake_x5c";
imdsRequest.bodyParameters = {
cnf: JSON.stringify({
jwk: {
kty: "RSA",
use: "sig",
alg: "RS256",
kid: sha256HashOfPublicKey,
x5c: [x5C],
},
}),
latch_key: "false",
};
/*
* TODO: Request SLC via "/credential" endpoint instead of using this fake object.
* This will be complicated the current acquireTokenWithManagedIdentity function in
* BaseManagedIdentitySource is not built to handle this request.
*/
const shortLivedCredential: ShortLivedCredential = {
client_id: "fake_string",
credential: "fake_string",
expires_in: 3599,
identity_type: "fake_string",
refresh_in: 3599,
region: "fake_string",
regional_token_url: "fake_string",
tenant_id: "fake_string",
};
const estsRequest: ManagedIdentityRequestParameters =
new ManagedIdentityRequestParameters(
HttpMethod.POST,
`${shortLivedCredential.regional_token_url}/${shortLivedCredential.tenant_id}/oauth2/v2.0/token`
);
// TODO: define constants for these values
estsRequest.bodyParameters = {
grant_type: "client_credentials",
scope: "https://management.azure.com/.default",
client_id: shortLivedCredential.client_id,
client_assertion: shortLivedCredential.credential,
client_assertion_type:
"urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
};
/*
* TODO:
* 1. Re-work the HttpClient to handle the self-signed mTLS certificate
* 2. Add functionality to ManagedIdentityRequestParameters to handle the self-signed mTLS certificate
*/
/*
* const agent = new Agent({
* cert: mTLSCertificatePem,
* key: privateKeyPem,
* ca: mTLSCertificatePem,
* });
* estsRequest.agent = agent;
*/
return estsRequest;
}
}