, , ,

Securing Nutanix API Access: Service Accounts, Keys, and Least Privilege

5 min read

Most Nutanix automation starts the same way. Someone writes a script, tests it with their own admin credentials, it works, and those credentials end up in a scheduled job. Nobody decides to do this, it just happens, one convenient step at a time.

The problem surfaces later: when that person changes role, when a password rotates, or when an audit asks which identity performed a change and the answer is a named individual who was asleep at the time.

Applies to: Prism Central v4 IAM APIs. API key authentication requires a recent Prism Central and AOS release, verify support on your version before designing around it.

Why basic authentication is not the destination: Basic authentication with a user account is the right way to make a first call. It is the wrong way to run production automation, for reasons beyond the obvious credential hygiene:

  • The identity belongs to a person, so attribution in the audit log is misleading
  • Offboarding that person breaks the automation, usually at an inconvenient moment
  • Human accounts tend to carry broad permissions the script does not need
  • Where Prism Central authenticates against an external directory, every request drives a directory lookup

That last point is a practical scaling concern rather than a security one. A job making thousands of calls with basic authentication generates thousands of directory authentications.

Service accounts and API keys: Prism Central IAM provides an identity type intended for exactly this purpose, described as a user of type service account. API key authentication is available only for service accounts, you cannot issue a key against a standard user account.

The workflow is:

  1. Create a service account through the v4 IAM API.
  2. Create an API key associated with that service account.
  3. Create an authorization policy granting only the permissions the automation needs, and assign the service account to it.
  4. Send the key on subsequent requests using the X-Ntnx-Api-Key header.

There are two operational caveats that will shape how you implement this.

First, the key is displayed once. If it is not captured into a secret store at the moment of creation, it is gone, and you will be issuing a new one.

Second, service accounts and API keys are not managed in the Prism Central UI. Creation and key issuance must be done programmatically through the v4 IAM APIs or SDKs. Service accounts also cannot be added to an authorization policy through the interface, though they can be removed through it.

That asymmetry has a real consequence: your API identities are configured through code that lives somewhere. Treat that code as part of the security control, keep it in version control, and make sure someone other than its author can find it.

Least privilege is the whole point: A service account assigned a Super Admin role is easier to set up and defeats most of the benefit. Authorization policies make full use of Prism Central role-based access control, so the permissions can be narrowed to what the automation actually performs.

The design questions are the same ones that apply to human access — which operations, against which resources — and they are covered in more depth in the discussion of roles, scope, and authorization policies in Fine-Grained RBAC in Prism Central.

The practical difference is that a service account is easier to scope correctly than a person, because its job is narrow and known. A backup integration reads VM inventory and creates recovery points. It has no reason to modify networking or manage users.

Give each integration its own service account rather than sharing one across every automation. Shared identities make it impossible to tell from the audit log which system made a change, and they force you to grant the union of every consumer’s permissions.

Handling the credential

  • Store keys in a secret manager, not in the script, a config file, or a pipeline variable in plain text
  • Keep them out of version control, and check the history if you suspect one was committed
  • Make sure logging and error handling never echo the header value
  • Plan rotation before you need it, including how a key is replaced without an outage
  • Record which team owns each service account and what it is for

Ownership is the item most often skipped and the one that hurts most. An unattributed service account with broad permissions is something nobody feels able to disable, so it survives indefinitely.

Review it like any other access: API identities should appear in the same access review as human accounts. Check for service accounts whose integration has been decommissioned, keys that have never been rotated, permissions that were widened to fix a failure and never narrowed again, and accounts with no documented owner.

Test the boundary too. Confirming that the automation can do its job proves very little on its own; confirming that it cannot do anything else is the part that demonstrates the scope actually holds.

Summary: Use basic authentication to prove a call works, then move automation onto a dedicated service account with an API key scoped by an authorization policy. Capture the key at creation, because it is shown only once, and expect to do the whole setup through the v4 IAM APIs rather than the UI.

One service account per integration, least privilege by default, an owner recorded for each, and API identities included in your regular access reviews.

Series Links:

Official Resources

Nutanix v4 API IntroductionNutanix API User GuideNutanix Developer Portal


What Do You Think? Do your Nutanix integrations each have their own service account, or is there still a shared automation account doing most of the work?