I’m reviving vault in our environment, it hasn’t been touched for the majority of last year. I’m still able of running some integration tests and creating/reading/deleting secrets. This is my .hcl file which I’m able to do these things.
path "secret/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
path "secret_tests/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
Problem comes when I try to delete versions of a secret… (From the UI I can do it oddly enough)
I read this Issue and also here docs , and tried to add new policies like these, trying to also specify the full path until the key:
path "secret/destroy/authserver/data-protection/*" {
capabilities = ["update"]
}
path "secret_tests/destroy/authserver/data-protection/*" {
capabilities = ["update"]
}
path "secret/delete/authserver/data-protection/*" {
capabilities = ["update"]
}
path "secret_tests/delete/authserver/data-protection/*" {
capabilities = ["update"]
}
path "secret/delete/*" {
capabilities = ["update"]
}
path "secret_tests/delete/*" {
capabilities = ["update"]
}
path "secret/destroy/*" {
capabilities = ["update"]
}
path "secret_tests/destroy/*" {
capabilities = ["update"]
}
None has worked, my code still breaks with a permission denied exception around here
await VaultClient.V1.Secrets.KeyValue.V2.DestroySecretVersionsAsync(path, deletableSource.Select(v => int.Parse(v.Key)).ToList());
Please help
maxb
August 18, 2023, 7:30pm
2
greg-signi:
Please help
There are people here willing to do so, but you have not explained what your problem is.
You started off with a wide open policy that will let you do anything you need to a couple of secrets engines:
greg-signi:
path "secret/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
path "secret_tests/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
But you said you had some kind of unspecified problem:
And for some reason chose to change your policy to something much more restrictive which doesn’t make much sense.
Based on the details presented so far, it is not possible to help, other than to tell you to go back to your first policy, which was more permissive.
I think I was clear where I was having the permission denied exception, its on this line of code:
await VaultClient.V1.Secrets.KeyValue.V2.DestroySecretVersionsAsync(path, versions).ToList());
It only happens with this method. I can read/write/delete secrets, just fine.
I started adding those policies since I’ve read that since V2 some things changed. For example, the github issue I mentioned, the user showed the same problem as me, despite having the generic base permissions, it was still giving him permission denied when trying to delete versions.
According to the docs, you can fix it with this sort of policy
path “secret/delete/dev/team-1/*” {
capabilities = [“update”]
}
Now I’m unsure in this path “secret/delete/{{dev}}/{{team-1}}/*”, what {{dev}} and {{team-1}} conrrespond to…
If it helps, my full path to the versions of the key I’m looking to delete is:
secret_tests/authserver/data-protection/{{key_name}}
Shouldn’t I specify a new path ? Like it says on the issue and the docs ?
maxb
August 18, 2023, 7:49pm
4
greg-signi:
I think I was clear where I was having the permission denied exception, its on this line of code:
await VaultClient.V1.Secrets.KeyValue.V2.DestroySecretVersionsAsync(path, versions).ToList());
It only happens with this method. I can read/write/delete secrets, just fine.
If you had in fact made this request, with the first policy you showed, it would have been successful.
Therefore there is something you are not showing.
Have you read the Github issue I’ve linked ? The user complains about the same problem I’m having, despite having the same policies as I had
path "secret/data/*" {
capabilities = [ "create", "read", "update", "delete", "list", "patch" ]
}
path "secret/metadata/*" {
capabilities = [ "create", "read", "update", "delete", "list", "patch" ]
}
With these policies he wasn’t still able to delete versions of the key
maxb
August 19, 2023, 8:48am
6
I’m literally the person who helped the other user in that issue.
Go back to using the very first policy you posted in this topic. This will work.
Or if it does not, you have other policies affecting you that you are not showing here.
I can show you the full code, but it is as I said. Nothing changes from the client, or policies, during this method execution…
public async Task<IEnumerable<SecretKeyVersion>> DeleteAllVersionsAsync(string path, string key, TimeSpan deletionInterval, int? collectionSize = null)
{
ArgumentValidatorHelper.ThrowIfNullOrEmpty(path);
ArgumentValidatorHelper.ThrowIfNullOrEmpty(key);
string pathKey = MakePath(path, key);
_logger.LogDebug("Trying to delete all secret versions from: '{SecretId}' older than {Minutes} minutes.", pathKey, deletionInterval.Minutes);
try
{
Secret<FullSecretMetadata> secretData =
await VaultClient.V1.Secrets.KeyValue.V2
.ReadSecretMetadataAsync(
pathKey,
mountPoint: _options.MountPoint);
DateTimeOffset minCreateDate = DateTimeOffset.Now.Subtract(deletionInterval);
var versions = secretData.Data.Versions
.Where(v =>
{
var createDate = DateTimeOffset.Parse(v.Value.CreatedTime, CultureInfo.CurrentUICulture);
return createDate < minCreateDate;
});
if (versions.Any())
{
var deletableSource = versions;
if (collectionSize != null)
{
int diff = (int)(collectionSize - deletableSource.Count());
if (diff < RotationKeys.MinimumRequiredVersions)
{
deletableSource = deletableSource.OrderBy(sv => DateTime.Parse(sv.Value.CreatedTime, CultureInfo.CurrentUICulture).ToUniversalTime()).Skip(RotationKeys.MinimumRequiredVersions - diff);
}
}
// THROWS EXCEPTION HERE: Permission Denied!
await VaultClient.V1.Secrets.KeyValue.V2.DestroySecretVersionsAsync(path, deletableSource.Select(v => int.Parse(v.Key)).ToList());
}
_logger.LogDebug("Deleted versions: {versions}", string.Join(",", versions));
return versions.Select(v => new SecretKeyVersion(DateTime.Parse(v.Value.CreatedTime, CultureInfo.CurrentUICulture).ToUniversalTime(), $"{key}:{v.Key}"));
}
catch (VaultApiException exception)
{
// since Vault returns a VaultApiException when storage don´t contains any secret on it,
// we must catch this and che the StatusCode.
if (exception.StatusCode != 404)
{
ForceReconnectVaultClient = true;
throw;
}
_logger.LogTrace("*** Vault - No secret found on path '{PathKey}'", pathKey);
}
catch
{
ForceReconnectVaultClient = true;
throw;
}
return Enumerable.Empty<SecretKeyVersion>();
}
During execution, its possible to see the policies I have…
Prior to execution I do a vault policy read authserver
vault policy read authserver
path “secret/" {
capabilities = [“create”, “read”, “update”, “delete”, “list”]
}
path "secret_tests/ ” {
capabilities = [“create”, “read”, “update”, “delete”, “list”]
}
It was the mountPoint parameter that was missing
thanks for u help