Skip to content

Commit 34ab400

Browse files
konidev20rajanadar
andauthored
feat-add-oidc-endpoints (rajanadar#309)
* fix: create named key API * feat: add read named key API * feat: add create, read and update role info * chore: update the implementation * chore: update the read role reponse object * fix: endpoints * fix: update interface for read role info * chore: add null checks * feat: add delete endpoints * fix: typo in ReadRoleReponse class name * feat: add wrapTimeToLive for PullNewSecretIdAsync * chore: update documentation * fix: remove Newtonsoft.Json references * chore: update the name of the keyName parameter --------- Co-authored-by: Raja Nadar <rajnadar@expediagroup.com>
1 parent a73f34c commit 34ab400

11 files changed

+260
-3
lines changed

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## 1.13.0.2 (TBD)
2+
3+
**IMROVEMENTS:**
4+
5+
* [GH-309](https://github.com/rajanadar/VaultSharp/issues/309) identity/oidc/key: create, read, update and delete apis.
6+
* [GH-309](https://github.com/rajanadar/VaultSharp/issues/309) identity/oidc/role: create, read, update and delete apis.
7+
* [GH-309](https://github.com/rajanadar/VaultSharp/issues/309) auth/approle: ````PullNewSecretIdAsync``` allows for reponse wrapping using ```wrapTimeToLive``` parameter
8+
19
## 1.13.0.1 (April 03, 2023)
210

311
**BUG FIXES:**

src/VaultSharp/V1/AuthMethods/AppRole/AppRoleAuthMethodProvider.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,12 @@ public async Task WriteRoleIdAsync(string roleName, RoleIdInfo roleIdInfo, strin
6868
await _polymath.MakeVaultApiRequest("v1/auth/" + mountPoint.Trim('/') + "/role/" + roleName.Trim('/') + "/role-id", HttpMethod.Post, requestData: roleIdInfo).ConfigureAwait(_polymath.VaultClientSettings.ContinueAsyncTasksOnCapturedContext);
6969
}
7070

71-
public async Task<Secret<SecretIdInfo>> PullNewSecretIdAsync(string roleName, PullSecretIdRequestOptions secretIdRequestOptions = null, string mountPoint = AuthMethodDefaultPaths.AppRole)
71+
public async Task<Secret<SecretIdInfo>> PullNewSecretIdAsync(string roleName, PullSecretIdRequestOptions secretIdRequestOptions = null, string mountPoint = AuthMethodDefaultPaths.AppRole, string wrapTimeToLive = null)
7272
{
7373
Checker.NotNull(mountPoint, "mountPoint");
7474
Checker.NotNull(roleName, "roleName");
7575

76-
return await _polymath.MakeVaultApiRequest<Secret<SecretIdInfo>>("v1/auth/" + mountPoint.Trim('/') + "/role/" + roleName.Trim('/') + "/secret-id", HttpMethod.Post, secretIdRequestOptions).ConfigureAwait(_polymath.VaultClientSettings.ContinueAsyncTasksOnCapturedContext);
76+
return await _polymath.MakeVaultApiRequest<Secret<SecretIdInfo>>("v1/auth/" + mountPoint.Trim('/') + "/role/" + roleName.Trim('/') + "/secret-id", HttpMethod.Post, secretIdRequestOptions, wrapTimeToLive: wrapTimeToLive).ConfigureAwait(_polymath.VaultClientSettings.ContinueAsyncTasksOnCapturedContext);
7777
}
7878

7979
public async Task<Secret<ListInfo>> ReadAllSecretIdAccessorsAsync(string roleName, string mountPoint = AuthMethodDefaultPaths.AppRole)

src/VaultSharp/V1/AuthMethods/AppRole/IAppRoleAuthMethod.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,12 @@ public interface IAppRoleAuthMethod
9292
/// <param name="mountPoint"><para>[optional]</para>
9393
/// The mount point for the Auth backend. Defaults to <see cref="AuthMethodDefaultPaths.AppRole" />
9494
/// Provide a value only if you have customized the mount point.</param>
95+
/// <param name="wrapTimeToLive">
96+
/// <para>[optional]</para>
97+
/// The TTL for the token and can be either an integer number of seconds or a string duration of seconds.
98+
/// </param>
9599
/// <returns>The secret id info</returns>
96-
Task<Secret<SecretIdInfo>> PullNewSecretIdAsync(string roleName, PullSecretIdRequestOptions secretIdRequestOptions = null, string mountPoint = AuthMethodDefaultPaths.AppRole);
100+
Task<Secret<SecretIdInfo>> PullNewSecretIdAsync(string roleName, PullSecretIdRequestOptions secretIdRequestOptions = null, string mountPoint = AuthMethodDefaultPaths.AppRole, string wrapToTimeLive = null);
97101

98102
/// <summary>
99103
/// Lists the accessors of all the SecretIDs issued against the AppRole.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System.Collections.Generic;
2+
using System.Text.Json.Serialization;
3+
4+
namespace VaultSharp.V1.SecretsEngines.Identity
5+
{
6+
/// <summary>
7+
/// Request object to create a named key which is used to sign tokens.
8+
/// </summary>
9+
public class CreateNamedKeyRequest : NamedKeyInfo
10+
{
11+
/// <summary>
12+
/// Array of role client ids allowed to use this key for signing. If
13+
/// empty, no roles are allowed. If "*", all roles are allowed.
14+
/// </summary>
15+
[JsonPropertyName("allowed_client_ids")]
16+
public List<string> AllowedClientIDs { get; set; }
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace VaultSharp.V1.SecretsEngines.Identity
2+
{
3+
public class CreateRoleRequest : RoleInfo
4+
{
5+
6+
}
7+
}

src/VaultSharp/V1/SecretsEngines/Identity/IIdentitySecretsEngine.cs

+68
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,74 @@ namespace VaultSharp.V1.SecretsEngines.Identity
88
/// </summary>
99
public interface IIdentitySecretsEngine
1010
{
11+
/// <summary>
12+
/// Create or update a role. ID tokens are generated against a role and
13+
/// signed against a named key.
14+
/// </summary>
15+
/// <param name="roleName">Name of the role.</param>
16+
/// <param name="createRoleRequest">Request object ot create or update a role.</param>
17+
/// <param name="mountPoint"><para>[optional]</para>
18+
/// The mount point for the backend. Defaults to <see cref="SecretsEngineMountPoints.Identity" />
19+
/// Provide a value only if you have customized the Azure mount point.
20+
/// </param>
21+
/// <returns>This endpoint doesn't return anything.</returns>
22+
Task CreateRoleAsync(string roleName, CreateRoleRequest createRoleRequest, string mountPoint = null);
23+
24+
/// <summary>
25+
/// This endpoint queries a role and returs its configuration.
26+
/// </summary>
27+
/// <param name="roleName">Name of the role.</param>
28+
/// <param name="mountPoint"><para>[optional]</para>
29+
/// The mount point for the backend. Defaults to <see cref="SecretsEngineMountPoints.Identity" />
30+
/// Provide a value only if you have customized the Azure mount point.
31+
/// </param>
32+
/// <returns>The role information</returns>
33+
Task<ReadRoleResponse> ReadRoleAsync(string roleName, string mountPoint = null);
34+
35+
/// <summary>
36+
/// This endpoint deletes a role.
37+
/// </summary>
38+
/// <param name="roleName">Name of the role.</param>
39+
/// <param name="mountPoint"><para>[optional]</para>
40+
/// The mount point for the backend. Defaults to <see cref="SecretsEngineMountPoints.Identity" />
41+
/// Provide a value only if you have customized the Azure mount point.
42+
/// </param>
43+
/// <returns>This endpoint doesn't return anything</returns>
44+
Task DeleteRoleAsync(string roleName, string mountPoint = null);
45+
46+
/// <summary>
47+
/// This endpoint creates or updates a named key which is used by a role to sign tokens.
48+
/// </summary>
49+
/// <param name="keyName">Name of the named key.</param>
50+
/// <param name="mountPoint"><para>[optional]</para>
51+
/// The mount point for the backend. Defaults to <see cref="SecretsEngineMountPoints.Identity" />
52+
/// Provide a value only if you have customized the Azure mount point.
53+
/// </param>
54+
/// <param name="createNamedKeyRequest">Request object to create a named key.</param>
55+
/// <returns>This endpoint doesn't return anything.</returns>
56+
Task CreateNamedKeyAsync(string keyName, CreateNamedKeyRequest createNamedKeyRequest, string mountPoint = null);
57+
58+
/// <summary>
59+
/// This endpoint reads a named key which is used by a role to sign tokens.
60+
/// </summary>
61+
/// <param name="keyName">Name of the named key.</param>
62+
/// <param name="mountPoint"><para>[optional]</para>
63+
/// The mount point for the backend. Defaults to <see cref="SecretsEngineMountPoints.Identity" />
64+
/// Provide a value only if you have customized the Azure mount point.
65+
/// </param>
66+
Task<ReadNamedKeyResponse> ReadNamedKeyAsync(string keyName, string mountPoint = null);
67+
68+
/// <summary>
69+
/// This endpoint deletes a named key.
70+
/// </summary>
71+
/// <param name="keyName">Name of the key.</param>
72+
/// <param name="mountPoint"><para>[optional]</para>
73+
/// The mount point for the backend. Defaults to <see cref="SecretsEngineMountPoints.Identity" />
74+
/// Provide a value only if you have customized the Azure mount point.
75+
/// </param>
76+
/// <returns>This endpoint doesn't return anything</returns>
77+
Task DeleteNamedKeyAsync(string keyName, string mountPoint = null);
78+
1179
/// <summary>
1280
/// Use this endpoint to generate a signed ID (OIDC) token.
1381
/// </summary>

src/VaultSharp/V1/SecretsEngines/Identity/IdentitySecretsEngineProvider.cs

+70
Original file line numberDiff line numberDiff line change
@@ -172,5 +172,75 @@ await _polymath.MakeVaultApiRequest(
172172
mergeEntitiesRequest)
173173
.ConfigureAwait(_polymath.VaultClientSettings.ContinueAsyncTasksOnCapturedContext);
174174
}
175+
176+
public async Task CreateNamedKeyAsync(string keyName, CreateNamedKeyRequest createNamedKeyRequest, string mountPoint = null)
177+
{
178+
Checker.NotNull(keyName, "keyName");
179+
Checker.NotNull(createNamedKeyRequest, "createNamedKeyRequest");
180+
181+
await _polymath.MakeVaultApiRequest(
182+
mountPoint ?? _polymath.VaultClientSettings.SecretsEngineMountPoints.Identity,
183+
"/oidc/key/" + keyName.Trim('/'),
184+
HttpMethod.Post,
185+
createNamedKeyRequest)
186+
.ConfigureAwait(_polymath.VaultClientSettings.ContinueAsyncTasksOnCapturedContext);
187+
}
188+
189+
public async Task<ReadNamedKeyResponse> ReadNamedKeyAsync(string keyName, string mountPoint = null)
190+
{
191+
Checker.NotNull(keyName, "keyName");
192+
193+
return await _polymath.MakeVaultApiRequest<ReadNamedKeyResponse>(
194+
mountPoint ?? _polymath.VaultClientSettings.SecretsEngineMountPoints.Identity,
195+
"/oidc/key/" + keyName.Trim('/'),
196+
HttpMethod.Get)
197+
.ConfigureAwait(_polymath.VaultClientSettings.ContinueAsyncTasksOnCapturedContext);
198+
}
199+
200+
public async Task CreateRoleAsync(string roleName, CreateRoleRequest createRoleRequest, string mountPoint = null)
201+
{
202+
Checker.NotNull(roleName, "roleName");
203+
Checker.NotNull(createRoleRequest, "createRoleRequest");
204+
205+
await _polymath.MakeVaultApiRequest(
206+
mountPoint ?? _polymath.VaultClientSettings.SecretsEngineMountPoints.Identity,
207+
"/oidc/role/" + roleName.Trim('/'),
208+
HttpMethod.Post,
209+
createRoleRequest)
210+
.ConfigureAwait(_polymath.VaultClientSettings.ContinueAsyncTasksOnCapturedContext);
211+
}
212+
213+
public async Task<ReadRoleResponse> ReadRoleAsync(string roleName, string mountPoint = null)
214+
{
215+
Checker.NotNull(roleName, "roleName");
216+
217+
return await _polymath.MakeVaultApiRequest<ReadRoleResponse>(
218+
mountPoint ?? _polymath.VaultClientSettings.SecretsEngineMountPoints.Identity,
219+
"/oidc/role/" + roleName.Trim('/'),
220+
HttpMethod.Get)
221+
.ConfigureAwait(_polymath.VaultClientSettings.ContinueAsyncTasksOnCapturedContext);
222+
}
223+
224+
public async Task DeleteRoleAsync(string roleName, string mountPoint = null)
225+
{
226+
Checker.NotNull(roleName, "roleName");
227+
228+
await _polymath.MakeVaultApiRequest(
229+
mountPoint ?? _polymath.VaultClientSettings.SecretsEngineMountPoints.Identity,
230+
"/oidc/role/" + roleName.Trim('/'),
231+
HttpMethod.Delete)
232+
.ConfigureAwait(_polymath.VaultClientSettings.ContinueAsyncTasksOnCapturedContext);
233+
}
234+
235+
public async Task DeleteNamedKeyAsync(string keyName, string mountPoint = null)
236+
{
237+
Checker.NotNull(keyName, "keyName");
238+
239+
await _polymath.MakeVaultApiRequest(
240+
mountPoint ?? _polymath.VaultClientSettings.SecretsEngineMountPoints.Identity,
241+
"/oidc/key/" + keyName.Trim('/'),
242+
HttpMethod.Delete)
243+
.ConfigureAwait(_polymath.VaultClientSettings.ContinueAsyncTasksOnCapturedContext);
244+
}
175245
}
176246
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace VaultSharp.V1.SecretsEngines.Identity
4+
{
5+
public class NamedKeyInfo
6+
{
7+
/// <summary>
8+
/// How often to generate a new signing key. Uses duration format strings.
9+
/// </summary>
10+
/// <example>"24h"</example>
11+
[JsonPropertyName("rotation_period")]
12+
public string RotationPeriod { get; set; }
13+
14+
/// <summary>
15+
/// Controls how long the public portion of a signing key will be
16+
/// available for verification after being rotated. Uses duration format strings.
17+
/// </summary>
18+
/// <example>"24h"</example>
19+
[JsonPropertyName("verification_ttl")]
20+
public string VerificationTimeToLive { get; set; }
21+
22+
/// <summary>
23+
/// Signing algorithm to use. Allowed values are: RS256 (default),
24+
/// RS384, RS512, ES256, ES384, ES512, EdDSA.
25+
/// </summary>
26+
[JsonPropertyName("algorithm")]
27+
public string Algorithm { get; set; }
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace VaultSharp.V1.SecretsEngines.Identity
4+
{
5+
public class ReadNamedKeyResponse
6+
{
7+
[JsonPropertyName("data")]
8+
public NamedKeyInfo Data { get; set; }
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace VaultSharp.V1.SecretsEngines.Identity
4+
{
5+
public class ReadRoleResponse
6+
{
7+
[JsonPropertyName("data")]
8+
public RoleInfo Data { get; set; }
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace VaultSharp.V1.SecretsEngines.Identity
4+
{
5+
public class RoleInfo
6+
{
7+
/// <summary>
8+
/// A configured named key, the key must already exist.
9+
/// </summary>
10+
[JsonPropertyName("key")]
11+
public string Key { get; set; }
12+
13+
/// <summary>
14+
/// The template string to use for generating tokens.
15+
/// This may be in string-ified JSON or base64 format.
16+
/// </summary>
17+
[JsonPropertyName("template")]
18+
public string Template { get; set; }
19+
20+
/// <summary>
21+
/// Optional client ID. A random ID will be generated if left unset.
22+
/// </summary>
23+
[JsonPropertyName("client_id")]
24+
public string ClientId { get; set; }
25+
26+
/// <summary>
27+
/// TTL of the tokens generated against the role. Uses duration format
28+
/// strings.
29+
/// </summary>
30+
[JsonPropertyName("ttl")]
31+
public string TimeToLive { get; set; }
32+
}
33+
}

0 commit comments

Comments
 (0)