Join our Newsletter — 33% off our NHI Course
Home› Guides› Service Accounts in Snowflake Guide: Key-Pair Auth, Network…
Guide Non-Human Identity (NHI)

Service Accounts in Snowflake Guide: Key-Pair Auth, Network Policies and Service User Controls

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 27 October 2026 16 min read
On this page

Most Snowflake data leaves through pipelines, BI connectors and applications that sign in as service accounts, and those accounts are often the least governed identities in the warehouse. The 2024 UNC5537 campaign used credentials that had sat unrotated for years against accounts with no MFA and no network allow list, and Snowflake has since built a dedicated service user model: TYPE = SERVICE users that cannot hold passwords, named key pairs with expiry, programmatic access tokens that require a network policy, and workload identity federation. This guide is the operating manual for those non-human identities: how to create them, which credential to give each workload, how to fence them with network and authentication policies, how to migrate LEGACY_SERVICE users before password sign-in is removed, and how to detect misuse. It is written for Snowflake administrators, data platform engineers and the identity teams that own service accounts. The account-wide view, including human users, MFA and data masking, is in the Snowflake Security Guide. Product details were checked against Snowflake documentation on 27 October 2026.

Key takeaways

  • Type every non-human user as SERVICE. SERVICE users cannot log in with a password, enrol in MFA or carry name and password properties, which removes the single-factor password path UNC5537 abused.
  • Pick the credential by where the workload runs. Workload identity federation for AWS, Azure, Google Cloud and OIDC issuers (no stored secret), named key pairs elsewhere, programmatic access tokens only for tools that need a token, and never a password.
  • Fence each service user to its own network. A user-level network policy that allows only the workload's egress addresses or private endpoint makes a stolen key useless from anywhere else, and service users cannot even use a PAT without one.
  • One workload, one user, one role. Restrict key pairs and PATs to a single role, block ACCOUNTADMIN and SECURITYADMIN, and never let automation run as an administrator.
  • Finish the LEGACY_SERVICE migration now. Snowflake's estimated phase 3 (August to October 2026, rolling per account) migrates remaining LEGACY_SERVICE users to SERVICE and blocks their passwords, so any integration still sending a password will break.

How identity and access work in Snowflake for service users

A Snowflake user's TYPE property decides which authentication methods it may use. Privileges are granted to roles, roles to users, and each session runs with a primary role. Four policy types are evaluated in a fixed order: network policy, then authentication policy, then password policy (local authentication only), then session policy; if the network policy blocks a request, evaluation stops.

TYPEIntended forPasswordCredentials availableNotes
PERSON or NULLHumansAllowed, with a second factor under the phase-outSSO, password with MFA, PATNot for automation
SERVICEPipelines, applications, integrationsNot allowedKey pair, PAT, OAuth, workload identity federationCannot enrol in MFA; cannot have FIRST_NAME, LAST_NAME, PASSWORD, MUST_CHANGE_PASSWORD or MINS_TO_BYPASS_MFA
SERVICE_AGENTAI agents with their own identityNot allowedWorkload identity federation, key pair, PATNo SAML SSO; PATs do not need a network policy, so add one yourself
LEGACY_SERVICEOld integrations that send a passwordAllowed until deprecationPassword, plus other methodsBeing deprecated; migrated to SERVICE in phase 3
SNOWFLAKE_SERVICESnowpark Container Services, created by SnowflakeNot applicableManaged by SnowflakeAdministrators cannot create or convert to it

Snowflake's published plan for removing single-factor password sign-ins sets estimated, rolling dates: from May to July 2026 no new LEGACY_SERVICE users can be created and existing users cannot be changed to that type; from August to October 2026 the type is fully deprecated, remaining users are migrated to TYPE = SERVICE and password authentication is blocked. Snowflake notifies each account of its enforcement date, so check your own notice rather than assuming the window.

Choosing the credential

WorkloadRecommended credentialWhyWatch for
Runs in AWS, Azure, Google Cloud, Kubernetes or a CI system with an OIDC issuerWorkload identity federationShort-lived cloud token, no secret stored anywhereScope OIDC_AUDIENCE_LIST to your account; unique issuer and subject per user
On-premises ETL, scheduled jobs on fixed hostsNamed key pair (RSA 2048-bit minimum, encrypted private key)Private key never leaves the host; supports expiry and role restrictionSpark, Kafka connectors and the Go driver accept only unencrypted keys
REST or SQL API callers, SaaS tools with only a password fieldProgrammatic access tokenExpiry, role restriction and mandatory network policyA bearer secret: anyone holding it can replay it from an allowed address
Applications already using your identity provider for machine-to-machine flowsExternal OAuthCentral policy and revocation at the identity providerIntegration-level network policies override user-level ones
AnythingPassword (LEGACY_SERVICE)NoneExactly the credential UNC5537 replayed; being removed

See the Workload Identity Federation Guide for the cloud-side configuration and the Service Account Security Guide for ownership and lifecycle practices that apply across platforms.

Admin roles and privileged access

Service users must never hold the administrative system roles. The controls that keep them out sit on the credentials themselves and on who can manage those credentials.

  • No automation as ACCOUNTADMIN or SECURITYADMIN: give each service user a custom functional role with only the warehouse, database and schema privileges it needs, and set it as DEFAULT_ROLE. Do not grant administrative roles to service users even "temporarily" for a deployment.
  • Restrict credentials to one role: named key pairs added with ALTER USER ... ADD KEY PAIR support role restriction and expiry, which the legacy RSA_PUBLIC_KEY property does not. PATs for service users require a ROLE_RESTRICTION by default (REQUIRE_ROLE_RESTRICTION_FOR_SERVICE_USERS), and secondary roles are ignored in PAT sessions.
  • Block privileged roles outright: set BLOCKED_ROLES_LIST so ACCOUNTADMIN and SECURITYADMIN can never be chosen as a PAT role restriction. It is checked at creation and at authentication.
  • Control who can mint credentials: adding key pairs, PATs and workload identities for another user needs OWNERSHIP of that user or MODIFY PROGRAMMATIC AUTHENTICATION METHODS on it. Grant that privilege to a small provisioning role, not to every data engineer, because anyone who holds it can give themselves a working credential for the service user.
  • Control who can change fences: creating network policies needs SECURITYADMIN or the CREATE NETWORK POLICY privilege; attaching one to a user needs OWNERSHIP of the user and USAGE on the policy. Applying authentication policies needs APPLY AUTHENTICATION POLICY. Keep these with security administrators.
  • Remember object ownership: objects created in a role-restricted PAT session are owned by the restricted role, and if that role is revoked or dropped the token stops working. Plan role changes with the pipeline owner.

See the Database Credential and Access Security Guide for how the same principles apply to other databases.

Integrations, API tokens and service accounts

Creating a service user properly

  1. Create from code: define the user in Terraform, SQL migrations or the SCIM API with TYPE = SERVICE, a COMMENT naming the owning team, workload and ticket, and a narrow DEFAULT_ROLE and DEFAULT_WAREHOUSE.
  2. Attach the user-level network policy first: before any credential exists, so there is never a window where a key works from anywhere.
  3. Attach the credential: a workload identity, a named key pair or a PAT, restricted to the functional role and with an expiry where the method supports it.
  4. Verify: for key pairs, compare RSA_PUBLIC_KEY_FP from DESC USER with the SHA-256 fingerprint of your public key; for any method, confirm the first successful login in LOGIN_HISTORY comes from the expected address.

Key pair lifecycle

  • Generation: RSA of at least 2048 bits (RS256, RS384 or RS512 signatures; ECDSA only in the Python driver). Snowflake says encrypted keys are generally safer, with PKCS#8 and AES-256-CBC; Triple DES is not recommended and the High Performance Snowpipe Streaming SDK rejects it. Keep the private key in a secrets manager and inject it at runtime. See the Secrets Management Guide.
  • Rotation: ALTER USER ... ROTATE KEY PAIR keeps the previous key valid for 24 hours by default; EXPIRE_ROTATED_KEY_PAIR_AFTER_HOURS changes the grace period and 0 expires it at once. Use the grace period for normal rotation and immediate expiry for suspected compromise.
  • Inventory: SHOW USER KEY PAIRS per user; remove keys with REMOVE KEY PAIR when a workload is retired. Users still on RSA_PUBLIC_KEY and RSA_PUBLIC_KEY_2 should move to named key pairs to gain expiry and role restriction.

Programmatic access tokens

  • Network policy is mandatory for service users: TYPE = SERVICE and LEGACY_SERVICE users must be subject to a network policy to generate or use a PAT, governed by PAT_POLICY NETWORK_POLICY_EVALUATION (default ENFORCED_REQUIRED). Do not relax it to NOT_ENFORCED, and avoid MINS_TO_BYPASS_NETWORK_POLICY_REQUIREMENT, which Snowflake itself advises against.
  • Expiry: default 15 days, maximum 365 by default. Lower MAX_EXPIRY_IN_DAYS to match your rotation standard; tokens beyond a lowered maximum stop authenticating, and expiry cannot be extended after creation.
  • Handling: the secret appears once in token_secret. Use it as a password in drivers (with the LOGIN_NAME as user) or as Authorization: Bearer for APIs. Rotate with ROTATE PROGRAMMATIC ACCESS TOKEN and EXPIRE_ROTATED_TOKEN_AFTER_HOURS; revoke with REMOVE PROGRAMMATIC ACCESS TOKEN.
  • Limits and safety nets: 15 tokens per user. Disabling a user disables its tokens and they stay disabled after re-enabling. Snowflake is a GitHub secret scanning partner and disables leaked tokens automatically, then emails the administrator and user. SYSTEM$DECODE_PAT identifies the user and token name for a secret found in code.
  • Authentication policy: if a policy restricts AUTHENTICATION_METHODS, include 'PROGRAMMATIC_ACCESS_TOKEN' only for the service users that need it.

Workload identity federation

Set the WORKLOAD_IDENTITY property (TYPE AWS, AZURE, GCP or OIDC) on a SERVICE or SERVICE_AGENT user and connect with authenticator='WORKLOAD_IDENTITY'. A user can hold up to 10 workload identities by default, added with ALTER USER ... ADD WORKLOAD IDENTITY. For OIDC, set OIDC_AUDIENCE_LIST to a value specific to your account: if omitted, the audience defaults to snowflakecomputing.com, which is shared across accounts. Snowflake caches issuer signing keys for up to 60 minutes, so keep old keys published for at least that long after rotating them. Restrict allowed providers and issuers with WORKLOAD_IDENTITY_POLICY in the authentication policy.

Logging and detection

The ACCOUNT_USAGE views keep a year of history: LOGIN_HISTORY covers 365 days, with up to 120 minutes of latency. The useful columns for service users are USER_NAME, CLIENT_IP, CLIENT_PRIVATE_LINK_ID, REPORTED_CLIENT_TYPE, FIRST_AUTHENTICATION_FACTOR, FIRST_AUTHENTICATION_FACTOR_ID (which credential was used), IS_SUCCESS, ERROR_CODE, LOGIN_DETAILS and AUTHORIZING_INTEGRATION_NAME. REPORTED_CLIENT_TYPE is self-reported and not authenticated, so use it as a signal, not proof.

DetectionData sourceWhat it catches
Service user login from an address or private endpoint never seen for that userLOGIN_HISTORY CLIENT_IP, CLIENT_PRIVATE_LINK_IDStolen key or token used elsewhere (should already fail under a tight network policy)
New client application string for a service userLOGIN_HISTORY REPORTED_CLIENT_TYPE, SESSIONSInteractive tools such as the DBeaver Ultimate client UNC5537 used, appearing on a pipeline identity
PAT use mapped to token namesLOGIN_HISTORY FIRST_AUTHENTICATION_FACTOR = 'PROGRAMMATIC_ACCESS_TOKEN' joined to CREDENTIALSTokens in use you did not expect; unused tokens to revoke
Repeated failures for one service userLOGIN_HISTORY IS_SUCCESS, ERROR_CODENetwork policy blocks, expired keys, credential guessing
Bulk staging and downloadQUERY_HISTORY for COPY INTO to stages followed by GETThe exfiltration pattern Mandiant described for UNC5537
Credential changesQUERY_HISTORY for ADD KEY PAIR, ADD PROGRAMMATIC ACCESS TOKEN, ADD WORKLOAD IDENTITY, SET NETWORK_POLICY, UNSETPersistence by adding a second credential or removing a fence

MITRE ATT&CK maps the abuse to T1078.004 Valid Accounts: Cloud Accounts and T1213.006 Data from Information Repositories: Databases, with T1552.004 Unsecured Credentials: Private Keys covering key files copied from hosts. Ship these views to your SIEM rather than querying ad hoc. See the Data Exfiltration Guide for downstream controls.

Metrics that show it is working

  • Service users by TYPE: 0 LEGACY_SERVICE users, and every non-human user TYPE = SERVICE or SERVICE_AGENT.
  • Network policy coverage: 100% of service users with a user-level network policy (not only the account policy).
  • Credential mix: share of service logins by workload identity federation rising over time; share by password at 0.
  • Credential age: 0 key pairs or PATs older than your rotation standard, and 0 PATs without a role restriction.
  • Ownership: 100% of service users with an owner in COMMENT or your inventory, and dormant service users disabled within a set number of days.

Hardening baseline

ControlSettingFramework
User typeTYPE = SERVICE for every non-human user; no LEGACY_SERVICENIST SP 800-53 AC-2, IA-9; CSF PR.AA-01
CredentialWorkload identity federation, else named key pair with expiry, else PAT; no passwordsIA-5; CSF PR.AA-03; ISO/IEC 27001 A.5.17
Service authentication policyALTER ACCOUNT SET AUTHENTICATION POLICY ... FOR ALL SERVICE USERS listing only the methods services useIA-2, IA-5; ISO A.8.5
Network policy per service userNetwork rules of TYPE IPV4, AWSVPCEID or AZURELINKID for the workload onlySC-7; CSF PR.AA-05
Private connectivityAllow rule for the endpoint ID plus a block rule for 0.0.0.0/0, since private-only rules do not affect public trafficSC-7
Least privilegeOne functional role; ROLE_RESTRICTION; BLOCKED_ROLES_LIST with ACCOUNTADMIN and SECURITYADMINAC-6; CSF PR.AA-05; ISO A.8.2
PAT limitsLowered MAX_EXPIRY_IN_DAYS; NETWORK_POLICY_EVALUATION = ENFORCED_REQUIREDIA-5
MonitoringLOGIN_HISTORY, SESSIONS, QUERY_HISTORY and CREDENTIALS to the SIEMAU-6; CSF DE.CM-03, PR.PS-04; ISO A.8.15

Rollout and migration plan

  1. Inventory: list users with TYPE LEGACY_SERVICE, NULL or PERSON that never use SSO and sign in from servers; these are your hidden service accounts. Join to LOGIN_HISTORY to see each one's addresses, clients and authentication factor over the last 365 days.
  2. Assign owners: no owner, no migration slot; disable unowned users after a notice period with ALTER USER ... SET DISABLED = TRUE, which is reversible.
  3. Pilot one workload: add a user-level network policy built from its observed addresses, attach a key pair or workload identity alongside the existing password, switch the client, and confirm logins in LOGIN_HISTORY.
  4. Convert the type: set TYPE = SERVICE, which removes password sign-in. Before converting, confirm in LOGIN_HISTORY that the user has had no successful password logins for a full business cycle. Plan rollback as giving the client a working key or token, not restoring the password: from phase 2, users cannot be changed back to LEGACY_SERVICE.
  5. Apply the service authentication policy: use FOR ALL SERVICE USERS once the pilot group is clean, keeping a less restrictive user-level policy on two monitored administrator users so a policy mistake cannot lock everyone out.
  6. Scale in waves: by business criticality, with the network policy always attached before the credential.
  7. Operate: scheduled rotation, quarterly review of roles and network rules, and alerts on credential changes.

Small estates with a handful of pipelines can do this in SQL in a week, using key pairs and strict IP rules. Large estates should manage users, policies and rules in Terraform or the SCIM API, standardise on workload identity federation, and treat any manually created service user as drift.

Common misconfigurations

  • Service accounts typed as people: a pipeline user left as PERSON or NULL with a password keeps exactly the exposure that the Snowflake Breach 2024 exploited: Mandiant found the stolen credentials had not been rotated, in some cases for up to four years, and the accounts had no MFA or network allow list.
  • Account policy only: a broad account-level network policy that covers the whole corporate range lets a stolen service key work from any laptop on the VPN. Service users need their own, tighter policy.
  • Legacy key property: keys set with RSA_PUBLIC_KEY have no expiry and no role restriction, so they live forever and can assume any role the user holds.
  • Unencrypted keys on shared hosts: connectors that only accept unencrypted keys (Spark, Kafka, Go driver) leave key files readable by anyone with host access. Lock file permissions and prefer federation for those workloads.
  • Shared OIDC audience: leaving OIDC_AUDIENCE_LIST at the default snowflakecomputing.com, which is shared across accounts, instead of a value for your account.
  • SERVICE_AGENT users without a fence: agent users can create PATs without a network policy, so an agent token can be replayed from anywhere unless you add one. See the Snowflake Cortex AI Security Guide for agent workloads.

Practitioner checklist

  • Inventory every non-human Snowflake user, including PERSON and NULL users that behave like services, and record an owner for each.
  • Migrate all LEGACY_SERVICE users to TYPE = SERVICE before your account's phase 3 enforcement date.
  • Give each workload its own service user, one functional role and a user-level network policy attached before any credential.
  • Use workload identity federation where the workload runs in a supported cloud or CI, and named key pairs with expiry elsewhere.
  • Restrict every key pair and PAT to one role and set BLOCKED_ROLES_LIST to exclude ACCOUNTADMIN and SECURITYADMIN.
  • Lower PAT maximum expiry, keep network policy evaluation at ENFORCED_REQUIRED, and store secrets only in a secrets manager.
  • Limit MODIFY PROGRAMMATIC AUTHENTICATION METHODS, network policy and authentication policy privileges to security administrators.
  • Apply an authentication policy for all service users that allows only the methods they use.
  • Stream LOGIN_HISTORY, SESSIONS, QUERY_HISTORY and CREDENTIALS to your SIEM and alert on new addresses, new clients and credential changes.
  • Rotate keys and tokens on schedule using the grace periods, and expire immediately on suspected compromise.

Standards and references

Related NHI Mgmt Group resources: Snowflake Security Guide · Database Credential and Access Security Guide · Service Account Security Guide · Workload Identity Federation Guide · Snowflake Breach 2024

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 27 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org