Why is my role's max TTL configuration being ignored?

I’m trying to create a database self-service role with a max TTL (time to live) of 7 days. I have two environments, both running Vault 1.12.1, and one is working as expected and in the other the logins disappear after an hour. Both roles were created via the same TF code (below) so I think there must be an overriding config somewhere but not sure where to start looking.

#new vault mount for db user self serve
resource "vault_mount" "db" {
  path = "database-self-serve"
  type = "database"
  default_lease_ttl_seconds =  0
  max_lease_ttl_seconds = 604800

#Configure vault connections to databases
resource "vault_database_secret_backend_connection" "database-1" {
  backend       = vault_mount.db.path
  name          = "${var.terraform_environment}-database-1"
  allowed_roles = formatlist("mysql-database-1-%s", local.allowed_role_list)

  mysql_aurora {
    connection_url = "{{username}}:{{password}}@tcp(${local.database-1_mysql_connection_url}:3306)/"
  data = {
    username = local.db_user
    password = var.connection_password
  lifecycle {
    ignore_changes = [data]

#configure vault roles which define the create user statements
resource "vault_database_secret_backend_role" "database-1-readonly" {
  count               = "${contains(local.allowed_role_list,"readonly") == true ? 1 : 0}"
  depends_on          = [vault_database_secret_backend_connection.database-1]
  backend             = vault_mount.db.path
  name                = "mysql-database-1-readonly"
  db_name             = "${var.terraform_environment}-database-1"
  creation_statements = ["${var.create_mysql_user}${var.readonly_mysql_permissions}"]
  default_ttl         = 604800
  max_ttl             = 604800

I’ve compared the Vault mount, connection, and role settings between the two environments and they match.

I’ve also tried setting the “vault_mount” default_lease_ttl_seconds to equal max_lease_ttl_seconds.

UPDATE: I’ve tried extending the default and max_TTL as well as dropping and recreating the secrets and still no luck. When I generate new credentials, I validate they exist/work and according to the Vault Lease (image below), they should expire in 30 days but are gone after an hour.

Regardless of what TTL ends up being set on the database secret lease, its lifetime is also bounded by the lifetime of the Vault login token used to create it.

Once the Vault login token expires or is explicitly revoked, secret leases created within that login session will be destroyed, even if the lease TTLs still have time to run.

Perhaps that could be what is happening here?

Thanks @maxb, that seems to be what’s happening. I was able to confirm once the token for my Vault sign-in expires, or gets revoked, the credential goes away. Any ideas on how to circumvent this limitation?

Some additional background: what we are trying to do is create a self-serve portal where if you belong to a certain AD group then you have the ability to generate your own database credentials. For example, you’re in the Developer group so you are able to generate yourself a sandbox login with developer permissions which would expire after X number of days.

Unfortunately, the notion that dynamic secrets (like the passwords generated by the database secrets engine) are time-bounded to the lifetime of the requesting Vault token, is pretty entrenched in the Vault design.

There’s no real need for this to be the case - there are other kinds of secrets which are not registered as dynamic secrets - but there’s no option in the database secrets engine to make this behaviour conditional.

In the long term, it may be worth looking to get such an option added to the database secrets engine.

In the short term, you’ll need to have your self-serve portal log in to Vault via an auth method, configured to create a token with TTL greater than the longest lived database credential you want to create. I would suggest you set the auth method up to return batch tokens, as that will avoid the dynamic secret leases being tracked against the token, since batch tokens are not written to Vault storage. Your self-serve portal will need to keep track of the remaining TTL on the token it is using to talk to Vault, and re-login as needed to ensure it remains large enough.

Hi @nate-hughes

In addition to what @maxb said, here are a few alternatives and comments from my own experience with a similar use-case:

  1. Use a root token for your service portal (I want to emphasize that while this is guaranteed to work, it’s not the recommended approach because of its security implications)
  2. Create an orphan, periodic token with a policy that allows it to manage its own tokens, system-wide leases and read database creds. Your self-service portal will be in charge of renewing the token within the configured interval or use something like Vault agent for that.
  3. Use Boundary+Vault instead (that’d be my choice). Be aware Boundary doesn’t support AD integration at the moment, so you’d need to use something that’s OIDC-compliant like Azure AD for your users’ auth method.