Stitchflow
JFrog logo

JFrog User Management API Guide

API workflow

How to automate user lifecycle operations through APIs with caveats that matter in production.

UpdatedMar 18, 2026

Summary and recommendation

The JFrog Access API (base: https://<server>/access/api/v1) is the current recommended surface for programmatic user management.

API Keys are deprecated in Artifactory 7.x - all integrations should use Bearer tokens scoped to applied-permissions/admin for user and group operations.

A parallel legacy surface exists under /artifactory/api;

JFrog recommends migrating away from it.

For identity graph use cases mapping users to groups, groups to Permission Targets, and Permission Targets to repositories

the Access API is the authoritative source, but assembling a complete access graph requires multiple sequential calls: list users, GET per-user for full detail, GET per-group for membership, and separate permission target queries.

API quick reference

Has user APIYes
Auth methodBearer token (JFrog Access Token) or HTTP Basic Auth. API Keys are deprecated as of Artifactory 7.x. Access Tokens are the recommended method.
Base URLOfficial docs
SCIM availableYes
SCIM plan requiredEnterprise X

Authentication

Auth method: Bearer token (JFrog Access Token) or HTTP Basic Auth. API Keys are deprecated as of Artifactory 7.x. Access Tokens are the recommended method.

Setup steps

  1. Log in to JFrog Platform as an admin.
  2. Navigate to Administration > User Management > Access Tokens.
  3. Click 'Generate Token', set scope (e.g., 'applied-permissions/admin' for full user management), expiry, and description.
  4. Copy the generated token; it is shown only once.
  5. Use the token as a Bearer token in the Authorization header: 'Authorization: Bearer '.
  6. Alternatively, use HTTP Basic Auth with username:password encoded in Base64 for legacy compatibility.

Required scopes

Scope Description Required for
applied-permissions/admin Full administrative access including user and group management. Create, update, delete users and groups; manage permissions.
applied-permissions/user Standard user-level access; cannot manage other users. Read own profile; generate own tokens.
member-of-groups: Scopes the token to permissions of a specific group. Delegated access scoped to a group's permissions.

User object / data model

Field Type Description On create On update Notes
username string Unique login name for the user. required immutable (used as path param) Case-sensitive in some contexts.
email string User's email address. required optional Used for notifications and identity.
password string User's password (hashed at rest). required (unless SSO-only) optional Not returned in GET responses.
admin boolean Whether the user has platform admin privileges. optional (default: false) optional Grants full administrative access.
profile_updatable boolean Whether the user can update their own profile. optional (default: true) optional
internal_password_disabled boolean Disables internal password login; forces SSO. optional (default: false) optional Relevant for SSO-enforced environments.
groups array[string] List of group names the user belongs to. optional optional Replaces existing group membership on update.
custom_data object Key-value map of custom attributes. optional optional Available in Access API v1.
status string Account status (e.g., 'enabled', 'disabled'). optional optional Used to disable accounts without deletion.
realm string Authentication realm (e.g., 'internal', 'ldap', 'saml'). optional read-only after creation Determines auth provider.
last_logged_in string (ISO 8601) Timestamp of last login. n/a read-only Returned in GET responses.
realm_attributes string Additional realm-specific attributes. optional optional Used for LDAP/SAML attribute mapping.

Core endpoints

List all users

  • Method: GET
  • URL: https://<server>/access/api/v1/users
  • Watch out for: Returns a summary list; individual GET is needed for full user details including custom_data.

Request example

GET /access/api/v1/users
Authorization: Bearer <token>

Response example

[
  {"username":"jsmith","email":"jsmith@example.com","admin":false,"groups":["developers"]},
  {"username":"admin","email":"admin@example.com","admin":true,"groups":[]}
]

Get a specific user

  • Method: GET
  • URL: https://<server>/access/api/v1/users/{username}
  • Watch out for: Password field is never returned in GET responses.

Request example

GET /access/api/v1/users/jsmith
Authorization: Bearer <token>

Response example

{
  "username": "jsmith",
  "email": "jsmith@example.com",
  "admin": false,
  "profile_updatable": true,
  "groups": ["developers"],
  "realm": "internal"
}

Create a user

  • Method: PUT
  • URL: https://<server>/access/api/v1/users/{username}
  • Watch out for: Uses PUT (idempotent); sending PUT to an existing username updates the user rather than erroring.

Request example

PUT /access/api/v1/users/jsmith
Content-Type: application/json
{
  "email": "jsmith@example.com",
  "password": "S3cur3P@ss",
  "admin": false,
  "groups": ["developers"]
}

Response example

{
  "username": "jsmith",
  "email": "jsmith@example.com",
  "admin": false,
  "groups": ["developers"]
}

Update a user

  • Method: PATCH
  • URL: https://<server>/access/api/v1/users/{username}
  • Watch out for: PATCH replaces the groups array entirely; partial group updates require fetching current groups first.

Request example

PATCH /access/api/v1/users/jsmith
Content-Type: application/json
{
  "email": "jsmith-new@example.com",
  "groups": ["developers","qa"]
}

Response example

{
  "username": "jsmith",
  "email": "jsmith-new@example.com",
  "groups": ["developers","qa"]
}

Delete a user

  • Method: DELETE
  • URL: https://<server>/access/api/v1/users/{username}
  • Watch out for: Deletion is immediate and irreversible; associated tokens are also revoked.

Request example

DELETE /access/api/v1/users/jsmith
Authorization: Bearer <token>

Response example

HTTP 204 No Content

List all groups

  • Method: GET
  • URL: https://<server>/access/api/v1/groups
  • Watch out for: Group membership details require a separate GET per group.

Request example

GET /access/api/v1/groups
Authorization: Bearer <token>

Response example

[
  {"group_name": "developers", "description": "Dev team"},
  {"group_name": "qa", "description": "QA team"}
]

Create or update a group

  • Method: PUT
  • URL: https://<server>/access/api/v1/groups/{groupName}
  • Watch out for: The members array is replaced wholesale on PUT; omitting it removes all members.

Request example

PUT /access/api/v1/groups/developers
Content-Type: application/json
{
  "description": "Development team",
  "members": ["jsmith","adoe"]
}

Response example

{
  "group_name": "developers",
  "description": "Development team",
  "members": ["jsmith","adoe"]
}

Create Access Token

  • Method: POST
  • URL: https://<server>/access/api/v1/tokens
  • Watch out for: The access_token value is returned only once at creation; store it securely immediately.

Request example

POST /access/api/v1/tokens
Content-Type: application/json
{
  "username": "jsmith",
  "scope": "applied-permissions/user",
  "expires_in": 3600
}

Response example

{
  "token_id": "abc123",
  "access_token": "eyJ...",
  "expires_in": 3600,
  "scope": "applied-permissions/user",
  "token_type": "Bearer"
}

Rate limits, pagination, and events

  • Rate limits: JFrog does not publicly document specific numeric rate limits for the REST API in official docs. Rate limiting behavior may vary by deployment type (SaaS vs. self-managed) and plan.

  • Rate-limit headers: No

  • Retry-After header: No

  • Rate-limit notes: No explicit rate limit values or headers are documented in official JFrog REST API documentation as of the policy date. Self-managed instances are limited by server resources.

  • Pagination method: offset

  • Default page size: 0

  • Max page size: 0

  • Pagination pointer: offset / limit (used in some list endpoints; not uniformly documented across all user endpoints)

  • Webhooks available: Yes

  • Webhook notes: JFrog Artifactory supports webhooks for repository and artifact events. User management events (user created/deleted) are not documented as webhook triggers in official docs.

  • Alternative event strategy: For user lifecycle events, poll the Access API or use SCIM provisioning callbacks via your IdP.

  • Webhook events: artifact.deployed, artifact.deleted, artifact.moved, artifact.copied, docker.push, docker.delete, release_bundle.created, release_bundle.signed, release_bundle.deleted

SCIM API status

  • SCIM available: Yes

  • SCIM version: 2.0

  • Plan required: Enterprise X

  • Endpoint: https:///access/api/v1/scim/v2

  • Supported operations: GET /Users – list users, GET /Users/{id} – get user, POST /Users – create user, PUT /Users/{id} – replace user, PATCH /Users/{id} – update user, DELETE /Users/{id} – delete user, GET /Groups – list groups, GET /Groups/{id} – get group, POST /Groups – create group, PUT /Groups/{id} – replace group, PATCH /Groups/{id} – update group, DELETE /Groups/{id} – delete group, GET /ServiceProviderConfig, GET /Schemas

Limitations:

  • Requires Enterprise X plan (SaaS or self-managed).
  • SCIM token must be generated from Administration > User Management > SCIM in the JFrog Platform UI.
  • SCIM provisioning manages platform-level users; repository-level permissions still require separate configuration.
  • Not all SCIM attributes map 1:1 to JFrog user fields; custom attributes may require custom_data mapping.
  • SCIM and direct REST API user management should not be used simultaneously for the same users to avoid conflicts.

Common scenarios

Three primary automation scenarios emerge from the available endpoints.

Provisioning a new developer requires a PUT to /access/api/v1/users/{username} with admin: false and a groups array

but the target group must exist first or the assignment may be silently ignored depending on platform version.

Offboarding without deletion uses PATCH with {"status": "disabled"} plus a token revocation call;

note that status field behavior should be validated against your specific platform version, as some versions use internal_password_disabled for SSO enforcement instead.

Bulk provisioning at Enterprise X tier uses the SCIM 2.0 endpoint at /access/api/v1/scim/v2

do not mix direct REST API writes with SCIM-managed accounts for the same users, as SCIM will overwrite manually set attributes on the next sync cycle.

Provision a new developer with group membership

  1. POST /access/api/v1/tokens to obtain an admin Bearer token (or use a pre-existing admin token).
  2. PUT /access/api/v1/users/{username} with email, password, admin:false, and groups:["developers"] to create the user.
  3. Verify creation with GET /access/api/v1/users/{username}.
  4. Optionally PUT /access/api/v1/groups/developers with updated members array to confirm group membership is reflected.

Watch out for: If the developers group does not yet exist, create it first with PUT /access/api/v1/groups/developers, otherwise the user creation will fail or the group assignment will be silently ignored depending on platform version.

Disable a user account (offboarding without deletion)

  1. PATCH /access/api/v1/users/{username} with body {"status": "disabled"} to disable login.
  2. POST /access/api/v1/tokens/revoke to revoke all active tokens for the user (use token_id or username filter).
  3. Optionally PATCH to remove the user from all groups by setting groups:[].

Watch out for: Status field behavior (enabled/disabled) should be verified against your specific JFrog Platform version; some versions use internal_password_disabled for SSO-only enforcement rather than a status field.

Bulk user provisioning via SCIM from an IdP (Enterprise X)

  1. Confirm Enterprise X plan is active on the JFrog Platform instance.
  2. Navigate to Administration > User Management > SCIM in the JFrog UI and generate a SCIM token.
  3. Configure your IdP (e.g., Okta, Azure AD) with SCIM base URL https:///access/api/v1/scim/v2 and the generated SCIM Bearer token.
  4. Map IdP user attributes to SCIM schema fields (userName → username, emails[0].value → email, groups → groups).
  5. Trigger a provisioning sync from the IdP; verify users appear in JFrog via GET /access/api/v1/scim/v2/Users.
  6. Test deprovisioning by removing a user in the IdP and confirming DELETE is propagated to JFrog.

Watch out for: Do not mix direct REST API user management with SCIM-provisioned users for the same accounts; SCIM will overwrite or conflict with manually set attributes on the next sync cycle.

Why building this yourself is a trap

Several non-obvious behaviors create integration risk. PUT on /users/{username} is upsert - it creates or updates silently, so create-only semantics require an existence check first. PATCH on a user replaces the groups array entirely;

partial group updates require fetching current membership before writing. Similarly, PUT on a group replaces the members array wholesale - omitting it removes all members.

Rate limits are not publicly documented for either SaaS or self-managed deployments, and no rate-limit headers are returned, so retry logic must be implemented defensively without guidance from the API itself. In HA self-managed deployments, the Access service runs on its own port (default 8082) and must be independently reachable.

Automate JFrog workflows without one-off scripts

Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.

Every app coverage, including apps without APIs
60+ app integrations plus browser automation for apps without APIs
IT graph reconciliation across apps and your IdP
Less than a week to launch, maintained as APIs and admin consoles change
SOC 2 Type II. ~2 hours of your team's time

UpdatedMar 18, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

15Five logo

15Five

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

15Five uses a fixed role-based permission model with six predefined roles: Account Admin, HR Admin, Billing Admin, Group Admin, Manager, and Employee. No custom roles can be constructed. User management lives at Settings gear → People → Manage people p

1Password logo

1Password

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

1Password's admin console at my.1password.com covers the full user lifecycle — invitations, group assignments, vault access, suspension, and deletion — without any third-party tooling. Like every app that mixes role-based and resource-level permissions

8x8 logo

8x8

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

8x8 Admin Console supports full lifecycle user management — create, deactivate, and delete — across its X Series unified communications platform. Every app a user can access (8x8 Work desktop, mobile, web, Agent Workspace) is gated by license assignmen