private async Task PolicyCreateExamples() { // Create a policy with multiple sub path objects. VaultPolicyContainer VP = new VaultPolicyContainer("TestingABC"); VaultPolicyPathItem vpi = new VaultPolicyPathItem("secret/TestA") { DeleteAllowed = true, ReadAllowed = true, CreateAllowed = true }; VP.AddPolicyPathObject(vpi); VaultPolicyPathItem vpi2 = new VaultPolicyPathItem("secret/TestB"); vpi2.ListAllowed = true; VP.AddPolicyPathObject(vpi2); VaultPolicyPathItem vpi3 = new VaultPolicyPathItem("secret/TestC"); vpi3.ListAllowed = true; vpi3.DeleteAllowed = true; vpi3.ReadAllowed = true; vpi3.SudoAllowed = true; // VP.PolicyPaths.Add(vpi3); var rc = await _vaultSystemBackend.SysPoliciesACLCreate(VP); }
/// <summary> /// Builds a policy for the full admins of the vault. /// </summary> /// <returns></returns> internal async Task <bool> BuildAdminPolicy() { // Create the Permission Paths // FullAdmins will have full control to the HashPath VaultPolicyPathItem hashPath = new VaultPolicyPathItem(true, VAULT_HASH_NAME, "/*"); hashPath.CRUDAllowed = true; // FullAdmins will have full control to the AppKey Vault VaultPolicyPathItem appPath = new VaultPolicyPathItem(true, VAULT_KEYCRYPT_NAME, "/*"); appPath.CRUDAllowed = true; // Now create the policy VaultPolicyContainer adminContainer = new VaultPolicyContainer("FullAdmin"); adminContainer.AddPolicyPathObject(hashPath); adminContainer.AddPolicyPathObject(appPath); bool success = await _vaultSystemBackend.SysPoliciesACLCreate(adminContainer); List <string> adminPolicies = new List <string>(); adminPolicies.Add(adminContainer.Name); // Associate the Admin Active Directory group to the policy. success = await _ldapAuthEngine.CreateGroupToPolicyMapping("_IT-SystemEngineers", adminPolicies); List <string> groups = await _ldapAuthEngine.ListGroups(); return(success); }
private async Task <(VaultPolicyContainer polContainer, VaultPolicyPathItem vppi)> SetupPolicy(string policyAppPath) { // B. Lets create a policy for root path. VaultPolicyPathItem vppi = new VaultPolicyPathItem(_beName, policyAppPath); vppi.Denied = true; // C. Create the Actual Policy container string polName = _uniqueKeys.GetKey("polCon"); VaultPolicyContainer polCon1 = new VaultPolicyContainer(polName); polCon1.AddPolicyPathObject(vppi); // D. Save Policy to Vault Instance. Assert.True(await _vaultSystemBackend.SysPoliciesACLCreate(polCon1), "SetupPolicy: A10: Saving the initial policy to Vault Instance failed."); return(polCon1, vppi); }
/// <summary> /// Creates the policies that this scenario needs. /// - polRoleMaster - Has FC on everything /// - polRole1 - full control on /path1 and everything below it. /// - polRole2 - Read Only access on /path1 and everything below it. No List capability /// - polAppA - Full control on /appData/appA /// - polAppB - Full control on /appData/appB /// - polShared - Read Only access on /shared/* /// </summary> /// <returns></returns> private async Task CreatePoliciesController() { // (Create / Get existing) policyContainer objects. _polRoleMaster = await GetPolicy("polRoleMaster"); _polRole1 = await GetPolicy("polRole1"); _polRole2 = await GetPolicy("polRole2"); _polRoleAppA = await GetPolicy("polRoleAppA"); _polRoleAppB = await GetPolicy("polRoleAppB"); _polSharedDB = await GetPolicy("polSharedDB"); _polSharedEmail = await GetPolicy("polSharedEmail"); _polCommon = await GetPolicy("appCommon"); // RoleMaster Policy. // Has access to everything in the KV2 backend. VaultPolicyPathItem vpItem1 = new VaultPolicyPathItem(_beKV2Name + "/data/*"); vpItem1.FullControl = true; _polRoleMaster.AddPolicyPathObject(vpItem1); if (!(await _vaultSystemBackend.SysPoliciesACLCreate(_polRoleMaster))) { Console.WriteLine("Unable to save the policies for the CreateRoles method"); } // Role1 Policy. FC on path1 and AppData VaultPolicyPathItem vppiR1P1 = new VaultPolicyPathItem(true, _beKV2Name, Constants.path1 + "/*"); vppiR1P1.FullControl = true; VaultPolicyPathItem vppiR1PAppData = new VaultPolicyPathItem(true, _beKV2Name, Constants.appData + "/*"); vppiR1PAppData.FullControl = true; _polRole1.AddPolicyPathObject(vppiR1P1); _polRole1.AddPolicyPathObject(vppiR1PAppData); if (!(await _vaultSystemBackend.SysPoliciesACLCreate(_polRole1))) { Console.WriteLine("Unable to save the policies for the Policy {0}", _polRole1.Name); throw new ApplicationException("Error saving Role1 Policies"); } if (!(await _vaultSystemBackend.SysPoliciesACLCreate(_polRole1))) { Console.WriteLine("Unable to save the policies for the Policy {0}", _polRole1.Name); } // Role2 Policy. RO on path1 VaultPolicyPathItem vppiR2P1 = new VaultPolicyPathItem(true, _beKV2Name, Constants.path1 + "/*"); vppiR2P1.ReadAllowed = true; _polRole2.AddPolicyPathObject(vppiR2P1); if (!(await _vaultSystemBackend.SysPoliciesACLCreate(_polRole2))) { Console.WriteLine("Unable to save the policies for the Policy {0}", _polRole2.Name); } VaultPolicyPathItem vpitemVar = new VaultPolicyPathItem(true, _beKV2Name, "appData/{{identity.entity.name}}/*"); vpitemVar.FullControl = true; _polCommon.AddPolicyPathObject(vpitemVar); if (!(await _vaultSystemBackend.SysPoliciesACLCreate(_polCommon))) { Console.WriteLine("Unable to save the policies for the Policy {0}", _polCommon.Name); } // RoleAppA Policy. FC on apps/AppA VaultPolicyPathItem vpItemA1 = new VaultPolicyPathItem(true, _beKV2Name, "appData/appA/*"); vpItemA1.FullControl = true; _polRoleAppA.AddPolicyPathObject(vpItemA1); if (!(await _vaultSystemBackend.SysPoliciesACLCreate(_polRoleAppA))) { Console.WriteLine("Unable to save the policies for the Policy {0}", _polRoleAppA.Name); } // RoleAppB Policy. FC on apps/AppB VaultPolicyPathItem vpItemB1 = new VaultPolicyPathItem(true, _beKV2Name, "appData/appB/*"); vpItemB1.FullControl = true; _polRoleAppB.AddPolicyPathObject(vpItemB1); if (!(await _vaultSystemBackend.SysPoliciesACLCreate(_polRoleAppB))) { Console.WriteLine("Unable to save the policies for the Policy {0}", _polRoleAppB.Name); } // Shared DB Policy VaultPolicyPathItem vpITemDB = new VaultPolicyPathItem(true, _beKV2Name, "shared/dbConfig"); _polSharedDB.AddPolicyPathObject(vpITemDB); vpITemDB.ReadAllowed = true; if (!(await _vaultSystemBackend.SysPoliciesACLCreate(_polSharedDB))) { Console.WriteLine("Unable to save the policies for the Policy {0}", _polSharedDB.Name); } // Shared Email Policy VaultPolicyPathItem vpItemEmail = new VaultPolicyPathItem(true, _beKV2Name, "shared/Email"); vpItemEmail.ReadAllowed = true; _polSharedEmail.AddPolicyPathObject(vpItemEmail); if (!(await _vaultSystemBackend.SysPoliciesACLCreate(_polSharedEmail))) { Console.WriteLine("Unable to save the policies for the Policy {0}", _polSharedEmail.Name); } }
/// <summary> /// Internal routine that processes the returned string from Vault and parses it into a VaultPolicyContainer object. /// </summary> /// <param name="data">The string data returned by Vault.</param> /// <param name="vp">VaultPolicyContainer object that should be filled in with the values from Vault.</param> /// <returns>True if successful.</returns> private bool ParseACLPaths(string data, VaultPolicyContainer vp) { string [] strDelimiters = { " ", "," }; string [] pathObjects = data.Split(strDelimiters, StringSplitOptions.RemoveEmptyEntries); bool starting = true; const string sPATH = "|PATH|"; const string sCAPA = "|CAPA|"; const string sLISTSTART = "{"; const string sLISTEND = "}"; const string sARRAYSTART = "["; const string sARRAYEND = "]"; const short iSTARTING = 0; const short iPATHLIST = 1; const short iPATHOPTIONS = 2; const short iCAP = 200; List <string> keyWords = new List <string>() { sPATH, sCAPA, sLISTSTART, sLISTEND, sARRAYSTART, sARRAYEND }; // We need to create a default object or else it will not compile. VaultPolicyPathItem newPathObj = new VaultPolicyPathItem("dummy/dummy2"); // Used so we can determine what type of path the permission is being applied to. Complicated. string KV2Path = ""; short iStep = iSTARTING; // Now process thru the data elements. for (int i = 0; i < pathObjects.Length; i++) { switch (iStep) { case iSTARTING: // PATH must be first value if starting. if (pathObjects [i] == sPATH) { iStep++; starting = true; // Make sure the next item is not a keyword. i++; if (keyWords.Contains(pathObjects [i])) { throw new FormatException("Found path keyword, but no value supplied for path NAME"); } else { VaultPolicyPathItem tempItem = new VaultPolicyPathItem(pathObjects [i]); KV2Path = tempItem.KV2_PathID; // If there is not a Policy permission object for this path in the Policy Container then use the new one. Otherwise use existing. if (!vp.PolicyPaths.TryGetValue(tempItem.Key, out newPathObj)) { newPathObj = tempItem; vp.AddPolicyPathObject(newPathObj); } } } else { string err = string.Join("", "First element must be the PATH identifier. Found: ", pathObjects [i].ToString(), " instead."); throw new FormatException(err); } break; case iPATHLIST: // We should be looking for the iPATH List identifier - { if ((pathObjects [i] == sLISTSTART) && (starting)) { starting = false; // Now see what type of parameter the next item is. i++; switch (pathObjects [i]) { case sCAPA: // It's a capabilities type. Now add items until we reach the end of the capabilities list. iStep = iCAP; // The next item should be opening array. if (pathObjects [++i] != sARRAYSTART) { throw new FormatException("Found the capabilities identifier, but did not find the opening array symbol - ["); } break; } // END switch pathObjects[i] } // END if sLISTSTART && starting break; case iCAP: if (pathObjects [i] == sLISTSTART) { iStep++; } else if (pathObjects [i] == sARRAYEND) { // Done with the capabilities. iStep = iPATHOPTIONS; } else { // It must be a valid capability AND we need to know what the path Prefix is so we can set the appropriate permission. switch (pathObjects [i]) { case "create": newPathObj.CreateAllowed = true; break; case "read": switch (KV2Path) { case "": case "data": newPathObj.ReadAllowed = true; break; case "metadata": newPathObj.ExtKV2_ViewMetaData = true; break; } newPathObj.ReadAllowed = true; break; case "update": switch (KV2Path) { case "": case "data": newPathObj.UpdateAllowed = true; break; case "delete": newPathObj.ExtKV2_DeleteAnyKeyVersion = true; break; case "undelete": newPathObj.ExtKV2_UndeleteSecret = true; break; case "destroy": newPathObj.ExtKV2_DestroySecret = true; break; default: throw new DataException( "Trying to set Update Permission for a VaultPolicyPathItem object resulted in arriving at an unexpected code path. Do not know what to do. Aborting."); } break; case "delete": switch (KV2Path) { case "": case "data": newPathObj.DeleteAllowed = true; break; case "metadata": newPathObj.ExtKV2_DeleteMetaData = true; break; default: throw new DataException( "Trying to set Delete permission for a VaultPolicyPathItem object resulted in arriving at an unexpected code path. Do not know what to do. Aborting."); } break; case "list": switch (KV2Path) { case "": case "data": newPathObj.ListAllowed = true; break; case "metadata": newPathObj.ExtKV2_ListMetaData = true; break; default: throw new DataException( "Trying to set List permission for a VaultPolicyPathItem object resulted in arriving at an unexpected code path. Do not know what to do. Aborting."); } break; case "sudo": newPathObj.SudoAllowed = true; break; case "deny": newPathObj.Denied = true; break; } } break; // Search for PATH options case iPATHOPTIONS: if (pathObjects [i] == sLISTEND) { // Done with this path object. iStep = iSTARTING; } break; } // END SWITCH istep } // END of for loop. return(true); } // END of method.
public async Task TestTemplatedPolicies() { string appBE = _uniqueKeys.GetKey("appTE"); string kv2BE = _uniqueKeys.GetKey("kv2TE"); // 1A - Setup backends needed for testing. // We need to setup a KV2 Secrets engine and also an AppRole Backend. // Create an Authentication method of App Role. - This only needs to be done when the Auth method is created. AuthMethod am = new AuthMethod(appBE, EnumAuthMethods.AppRole); await _vaultSystemBackend.AuthEnable(am); // Create a KV2 Secret Mount if it does not exist. VaultSystemBackend vaultSystemBackend = new VaultSystemBackend(_vaultAgentAPI.TokenID, _vaultAgentAPI); await vaultSystemBackend.SysMountCreate(kv2BE, "ClientTest KeyValue 2 Secrets", EnumSecretBackendTypes.KeyValueV2); // 1B. Now we can connect to the backends. VaultAgentAPI vault = await VaultServerRef.ConnectVault("PolicyBECapa"); //new VaultAgentAPI("capability", _vaultAgentAPI.IP, _vaultAgentAPI.Port, _vaultAgentAPI.TokenID); AppRoleAuthEngine authEngine = (AppRoleAuthEngine)vault.ConnectAuthenticationBackend(EnumBackendTypes.A_AppRole, appBE, appBE); KV2SecretEngine secretEngine = (KV2SecretEngine)vault.ConnectToSecretBackend(EnumSecretBackendTypes.KeyValueV2, "KV2 Secrets", kv2BE); IdentitySecretEngine idEngine = (IdentitySecretEngine)_vaultAgentAPI.ConnectToSecretBackend(EnumSecretBackendTypes.Identity); // 1C - Write out some values. TestContext.WriteLine("App Role Auth Backend: {0}", authEngine.Name); TestContext.WriteLine("KV2 Secret Backend: {0}", secretEngine.Name); // 2. Setup the policy to provide the permissions to test against. VaultPolicyContainer policyContainer = new VaultPolicyContainer("capa"); // 3. Now create an App Role & Secret ID. The app role in this case has no policies - it will get them from the Entity. string roleName = _uniqueKeys.GetKey("role"); AppRole appRole = new AppRole(roleName); appRole = await authEngine.SaveRoleAndReturnRoleObject(appRole); AppRoleSecret secretID = await authEngine.CreateSecretID(appRole.Name); // 4. Create an Entity and Entity Alias. // 4A. Get Authentication backend accessor. Dictionary <string, AuthMethod> authMethods = await vaultSystemBackend.AuthListAll(); AuthMethod authMethod = authMethods[authEngine.Name + "/"]; Assert.IsNotNull(authMethod, "B10: Expected to find the authentication backend. But did not."); string mountAccessor = authMethod.Accessor; // 4B. Create an entity for the app role. string name = _uniqueKeys.GetKey("EAR"); Entity entity = new Entity(roleName); entity.Policies.Add(policyContainer.Name); // 4C. Now save entity entity = await idEngine.SaveEntity(entity); Assert.IsNotNull(entity, "B20: Expected to receive an Entity object"); // 4D. Write out some values TestContext.WriteLine("Entity Name: {0}", entity.Name); TestContext.WriteLine("Entity ID: {0}", entity.Id); // 5. Create an alias that ties the Entity we just created to the AppRole in the authentication backend. Guid roleID = new Guid(appRole.RoleID); Guid aliasGuid = await idEngine.SaveAlias(entity.Id, mountAccessor, appRole.RoleID); Assert.AreNotEqual(aliasGuid.ToString(), Guid.Empty.ToString()); // 5B. Re-read the entity - it should now contain the alias. Entity fullEntity = await idEngine.ReadEntity(entity.Id); Assert.AreEqual(1, fullEntity.Aliases.Count, "B30: Expected the full entity to now contain the alias ID."); // 6. Now define the policy and save to Vault. policyContainer.PolicyPaths.Clear(); string appPath1 = "app/{{identity.entity.aliases." + mountAccessor + ".name}}/*"; VaultPolicyPathItem vppi1 = new VaultPolicyPathItem(kv2BE, "data/" + appPath1); VaultPolicyPathItem vppi2 = new VaultPolicyPathItem(kv2BE, "data/app/appA/subItem/*"); VaultPolicyPathItem vppi3 = new VaultPolicyPathItem(kv2BE, "data/shared/common/*"); VaultPolicyPathItem vppi4 = new VaultPolicyPathItem(kv2BE, "data/shared/info/*"); vppi1.FullControl = true; vppi2.FullControl = true; vppi3.CRUDAllowed = true; vppi4.ReadAllowed = true; policyContainer.AddPolicyPathObject(vppi1); policyContainer.AddPolicyPathObject(vppi2); policyContainer.AddPolicyPathObject(vppi3); policyContainer.AddPolicyPathObject(vppi4); await _vaultSystemBackend.SysPoliciesACLCreate(policyContainer); // 7. Now we can login to get a token.. Validate the entity policy has been set on token. Token token = await authEngine.Login(appRole.RoleID, secretID.ID); Assert.IsNotNull("B40: A valid token was not received."); CollectionAssert.Contains(token.IdentityPolicies, policyContainer.Name, "B100: Did not find the policy that should have been applied from the entity."); // 8. Now we can finally test the capabilities of that token. List <string> paths = new List <string>(); string pathBase = kv2BE + "/data/app/" + fullEntity.Aliases[0].Name + "/config"; string metaBase = kv2BE + "/metadata/app" + fullEntity.Aliases[0].Name + "/config"; string path1 = pathBase; string path2 = pathBase + "/subItem"; string path3 = kv2BE + "/data/shared/common/testEntry"; paths.Add(path1); paths.Add(path2); paths.Add(path3); Dictionary <string, List <string> > permissions; permissions = await _vaultSystemBackend.GetTokenCapabilityOnPaths(token.ID, paths); // 9. Validate the permission results. Assert.AreEqual(3, permissions.Count, "B130: Expected to receive 3 permission objects back."); Assert.AreEqual(6, permissions[path1].Count, "B140: Expected the item: " + path1 + " to contain 6 permissions."); Assert.AreEqual(6, permissions[path2].Count, "B150: Expected the item: " + path2 + " to contain 6 permissions."); Assert.AreEqual(4, permissions[path3].Count, "B160: Expected the item: " + path3 + " to contain 3 permissions."); CollectionAssert.Contains(permissions[path3], "create", "B170: Expected the permission to be create for path: " + path3); CollectionAssert.Contains(permissions[path3], "read", "B171: Expected the permission to be read for path: " + path3); CollectionAssert.Contains(permissions[path3], "update", "B172: Expected the permission to be update for path: " + path3); CollectionAssert.Contains(permissions[path3], "delete", "B173: Expected the permission to be read for path: " + path3); // 10. Try to create a secret at path 1 string secName1 = _uniqueKeys.GetKey("sec1"); KV2Secret secret1 = new KV2Secret("config", "app/" + fullEntity.Aliases[0].Name); secret1.Attributes.Add("version", "v12.2"); Assert.True(await secretEngine.SaveSecret(secret1, KV2EnumSecretSaveOptions.AlwaysAllow), "B200: Save of secret did not work. Check permissions."); // 11. Create and delete a secret at path3. KV2Secret secret2 = new KV2Secret("options", "shared/common/testEntry"); secret2.Attributes.Add("color", "blue"); secret2.Attributes.Add("size", "Large"); Assert.True(await secretEngine.SaveSecret(secret2, KV2EnumSecretSaveOptions.AlwaysAllow), "B210: Save of secret2 failed."); // Now delete it. Assert.True(await secretEngine.DeleteSecretVersion(secret2)); }
public async Task TestCapabilitiesFunctionality() { string appBE = _uniqueKeys.GetKey("appBE"); string kv2BE = _uniqueKeys.GetKey("kv2BE"); // 1 - Setup backends needed for testing. // We need to setup a KV2 Secrets engine and also an AppRole Backend. // Create an Authentication method of App Role. - This only needs to be done when the Auth method is created. AuthMethod am = new AuthMethod(appBE, EnumAuthMethods.AppRole); await _vaultSystemBackend.AuthEnable(am); // Create a KV2 Secret Mount if it does not exist. await _vaultSystemBackend.SysMountCreate(kv2BE, "ClientTest KeyValue 2 Secrets", EnumSecretBackendTypes.KeyValueV2); // Now we create secret backend VaultAgentAPI vault = await VaultServerRef.ConnectVault("PolicyBeCapa2"); AppRoleAuthEngine authEngine = (AppRoleAuthEngine)vault.ConnectAuthenticationBackend(EnumBackendTypes.A_AppRole, appBE, appBE); KV2SecretEngine secretEngine = (KV2SecretEngine)vault.ConnectToSecretBackend(EnumSecretBackendTypes.KeyValueV2, "KV2 Secrets", kv2BE); // 2. Setup the policy to provide the permissions to test against. VaultPolicyContainer policyContainer = new VaultPolicyContainer("capa"); VaultPolicyPathItem vppi1 = new VaultPolicyPathItem(kv2BE, "data/app/appA/*"); VaultPolicyPathItem vppi2 = new VaultPolicyPathItem(kv2BE + "data/app/appA/subItem/*"); VaultPolicyPathItem vppi3 = new VaultPolicyPathItem(kv2BE + "metadata/app/appA/*"); VaultPolicyPathItem vppi4 = new VaultPolicyPathItem(kv2BE + "data/shared/*"); vppi1.FullControl = true; vppi2.FullControl = true; vppi3.ReadAllowed = true; vppi4.ReadAllowed = true; policyContainer.AddPolicyPathObject(vppi1); policyContainer.AddPolicyPathObject(vppi2); policyContainer.AddPolicyPathObject(vppi3); policyContainer.AddPolicyPathObject(vppi4); await _vaultSystemBackend.SysPoliciesACLCreate(policyContainer); // 3. Now create an App Role & Secret ID string roleName = _uniqueKeys.GetKey("role"); AppRole appRole = new AppRole(roleName); appRole.Policies.Add(policyContainer.Name); appRole = await authEngine.SaveRoleAndReturnRoleObject(appRole); AppRoleSecret secretID = await authEngine.CreateSecretID(appRole.Name); // 4. Now we can create a token against that Token token = await authEngine.Login(appRole.RoleID, secretID.ID); // 5. Now we can finally test the capabilities of that token. List <string> paths = new List <string>(); string path1 = kv2BE + "/data/app/appA/subItem"; string path2 = kv2BE + "/data/app/appB/subItem"; string path3 = kv2BE + "/noaccess/app/appA"; string path4 = kv2BE + "/data/noaccess/app/appA/subItem"; paths.Add(path1); paths.Add(path2); paths.Add(path3); paths.Add(path4); Dictionary <string, List <string> > permissions; permissions = await _vaultSystemBackend.GetTokenCapabilityOnPaths(token.ID, paths); // 6. Validate the results. Assert.AreEqual(4, permissions.Count, "A10: Expected to receive 4 permission objects back."); Assert.AreEqual(6, permissions[path1].Count, "A20: Expected the item: " + path1 + " to contain 6 permissions."); Assert.AreEqual(1, permissions[path2].Count, "A30: Expected the item: " + path2 + " to contain 1 deny permission."); CollectionAssert.Contains(permissions[path2], "deny", "A35: Expected the permission to be deny for path: " + path2); Assert.AreEqual(1, permissions[path3].Count, "A40: Expected the item: " + path3 + " to contain 1 deny permission."); CollectionAssert.Contains(permissions[path3], "deny", "A35: Expected the permission to be deny for path: " + path3); Assert.AreEqual(1, permissions[path4].Count, "A40: Expected the item: " + path4 + " to contain 1 deny permission."); CollectionAssert.Contains(permissions[path4], "deny", "A35: Expected the permission to be deny for path: " + path4); }