Introduction
Because a secrets engine can be enabled at an arbitrary path (e.g. vault enable secrets aws -path=aws-secrets), it is not possible to prevent enabling with an ACL policy. Using Sentinel, it is possible to filter secrets engines by type via the data property (raw request data) in the request namespace and block the secrets engine(s) from being enabled.
Expected Outcome
Upon completion, the specific secrets engines called out in the example Sentinel policy (EGP) cannot be enabled in root, nor any namespaces.
Prerequisites
- Vault Enterprise
Use Case
There are particular secrets engines which need to be blocked from being enabled across Vault.
Procedure
NOTE: This example policy is for illustrative purposes and should not be used in a production environment. It is intended to show what is possible. Before implementing, be sure to test in a non-production environment.
1. Create the policy prevent-secrets.hcl
In this example policy, the azureand awssecrets engine types cannot be enabled.
import "strings"
prevent_engines = func() {
    # if policy is violated, the following will print:
    print("Secret engine type not allowed:", request.data.type)
    print("Namespace id:", namespace.id)
    print("Namespace path:", namespace.path)
    print("Request path:", request.path)
    if strings.has_prefix(request.path, "sys/mounts/") and
        request.operation in ["create", "update"] {
        if request.data.type in ["azure", "aws"] {
            print("Secret engine type not allowed:", request.data.type)
            return false
        }
    }
    if strings.has_prefix(request.path, "sys/mounts/") and
        request.operation in ["create", "update"] and
        strings.has_suffix(namespace.path, "/") {
        if request.data.type in ["azure", "aws"] {
            print("Secret engine type not allowed:", request.data.type)
            return false
        }
    }
    return true
}
engines_prevented = prevent_engines()
main = rule {
    engines_prevented
}The first if statement applies the filter in the root namespace. The second if statement applies the filter in all namespaces via strings.has_suffix(namespace.path, "/").
2. Set a var POLICY to the path where the policy is located: POLICY=/path/to/policy/prevent-secrets.hcl
3. Write the policy to Vault: vault write sys/policies/egp/prevent-secrets policy="${POLICY}" enforcement_level="hard-mandatory" paths="*"
In the above step, pathsis set to "*"which will evaluate all paths. This is so the policy is applied to root secrets engines i.e. sys/mounts/ and namespace secrets engines e.g. namespace/sys/mounts/
