Hi,
We’re building an ephemeral resource in our Terraform Provider that generates a short-lived OAuth2 access token via the Client Credentials flow (3600s TTL).
The resource has an optional revoke_on_closure flag. When enabled, we revoke the token at the end of the Terraform operation during
Close(). Our revocation endpoint (POST follows RFC 7009 and requires:
- The access token being revoked (in the request body)
- Client credentials for authentication (Basic auth with client_id:client_secret)
Since Close() only receives req.Private (not the original config or result data), we store the access_token, client_id, and client_secret in private state during Open() so they’re available for revocation in Close().
We have a few questions about this approach:
- What are the persistence and isolation guarantees of private state in ephemeral resources?
The private state docs describe private state for managed resources, where it is persisted in the state file. For ephemeral resources, our understanding is that private state is held in process memory only and never written to disk. Is this correct?
Is this documented or guaranteed anywhere for ephemeral resources specifically?
- Is private state the recommended way to pass data from Open() to Close()?
Close() doesn’t have access to the resource config or result data, only req.Private. For cleanup operations that need information from Open(), private state seems like the only option. Is this the intended pattern?
- Are there any security considerations we should be aware of when storing sensitive values (tokens, credentials) in ephemeral private state?
Our concern is that we’re storing three sensitive values (access_token, client_id, client_secret) in private state bytes. These
same values are already in process memory during Open() (as Go locals and in the Terraform model struct), so we don’t believe private state increases the attack surface. But we want to confirm there’s no scenario where ephemeral private state could be logged, serialized to a crash dump, or otherwise made visible outside the process.
For reference, we looked at how HashiCorp’s own Vault provider handles this. The vault_azure_access_credentials ephemeral resource
stores a lease_id in private state and revokes it in Close(). Their case is simpler because Vault’s revoke API only needs a lease ID (not credentials), but the pattern of using private state to pass cleanup data to Close() is the same.
Any guidance on these questions would be appreciated. This is one of the first ephemeral resources in the ecosystem that implements Close() with credential-dependent revocation, so we want to make sure we’re following best practices.