/// <summary> /// Returns credentials for a Vault AppRole. /// </summary> /// <param name="roleName">The role name.</param> /// <param name="cancellationToken">The optional <see cref="CancellationToken"/>.</param> /// <returns>The <see cref="HiveCredentials"/>.</returns> /// <exception cref="HttpException">Thrown for Vault communication problems.</exception> public async Task <HiveCredentials> GetAppRoleCredentialsAsync(string roleName, CancellationToken cancellationToken = default) { Covenant.Requires <ArgumentException>(HiveDefinition.IsValidName(roleName)); string roleId; string secretId; // Verify that the role exists. try { await ReadDynamicAsync($"auth/approle/role/{roleName}", cancellationToken : cancellationToken); } catch (Exception e) { throw new HttpException($"Unable to access Vault [AppRole={roleName}]", e); } // Fetch the role ID. try { var response = await ReadDynamicAsync($"auth/approle/role/{roleName}/role-id", cancellationToken : cancellationToken); roleId = response.role_id; } catch (Exception e) { throw new HttpException($"Unable to fetch the role ID for Vault [AppRole={roleName}]", e); } // Fetch a secret ID. try { var response = (await WriteJsonAsync($"auth/approle/role/{roleName}/secret-id", cancellationToken)).data; secretId = response.secret_id; } catch (Exception e) { throw new HttpException($"Unable to fetch the role ID for Vault [AppRole={roleName}]", e); } // Return the credentials. return(HiveCredentials.FromVaultRole(roleId, secretId)); }
//--------------------------------------------------------------------- // Static members /// <summary> /// Opens a Vault connection using <see cref="HiveCredentials"/>. /// </summary> /// <param name="uri">The Vault server URI.</param> /// <param name="credentials">The Vault credentials.</param> /// <returns>The <see cref="VaultClient"/>.</returns> public static VaultClient OpenWithToken(Uri uri, HiveCredentials credentials) { Covenant.Requires <ArgumentNullException>(uri != null); Covenant.Requires <ArgumentNullException>(credentials != null); var vaultClient = new VaultClient(uri); switch (credentials.Type) { case HiveCredentialsType.VaultToken: vaultClient.jsonClient.DefaultRequestHeaders.Add("X-Vault-Token", credentials.VaultToken); break; case HiveCredentialsType.VaultAppRole: dynamic loginPayload = new ExpandoObject(); loginPayload.role_id = credentials.VaultRoleId; loginPayload.secret_id = credentials.VaultSecretId; var loginResponse = vaultClient.jsonClient.PostAsync($"/{vaultApiVersion}/auth/approle/login", loginPayload).Result.AsDynamic(); vaultClient.jsonClient.DefaultRequestHeaders.Add("X-Vault-Token", (string)loginResponse.auth.client_token); break; default: throw new NotImplementedException($"Credentials type: {credentials.Type}"); } // $todo(jeff.lill): // // This should be set from config. See issue: // // https://github.com/jefflill/NeonForge/issues/253 vaultClient.AllowSelfSignedCertificates = true; return(vaultClient); }
/// <summary> /// Called internally by <see cref="HiveHelper.OpenHiveRemote(DebugSecrets, DebugConfigs, string, bool)"/> /// to create any requested Vault and Consul credentials and add them to the dictionary. /// </summary> /// <param name="hive">The attached hive.</param> /// <param name="hiveLogin">The hive login.</param> internal void Realize(HiveProxy hive, HiveLogin hiveLogin) { this.hiveLogin = hiveLogin; HiveCredentials credentials; foreach (var request in credentialRequests) { switch (request.Type) { case CredentialType.VaultToken: // Serialize the credentials as JSON and persist. credentials = HiveCredentials.FromVaultToken(request.Token); Add(request.SecretName, NeonHelper.JsonSerialize(credentials, Formatting.Indented)); break; case CredentialType.VaultAppRole: // Serialize the credentials as JSON and persist. credentials = VaultClient.GetAppRoleCredentialsAsync(request.RoleName).Result; Add(request.SecretName, NeonHelper.JsonSerialize(credentials, Formatting.Indented)); break; case CredentialType.ConsulToken: // $todo(jeff.lill): Implement this. break; } } }