Have a question? Want to report an issue? Contact JFrog support

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Overview

From version 5.0, Artifactory offers access tokens as a new and flexible means of authentication with a range of capabilities previously unavailable:

  • Cross-instance authentication
    Access tokens can be used for authentication, not only by the Artifactory instance or cluster where they were created, but also for other instances and clusters that are all part of the same "circle of trust" (described below).
     
  • User and non-user authentication
    The case for authenticating Artifactory users is clear, however access tokens can also be assigned to non-user entities such as CI server jobs.

  • Time-based access control 
    Access tokens have an expiry period so you can control the period of time for which you grant access. However, you may also delegate that control to the receiving user by making them refreshable

  • Flexible scope 
    By assigning Groups to tokens, you can control the level of access they provide.

 

 To support these capabilities, an access token has the following properties:

Subject
The user to which this access token is associated. If the user specified does not exist, Artifactory will create a corresponding transient user
Issuer
An identifier of the cluster on which the access token was created
Scope
The scope of access that the token provides. Access to the REST API is always provided by default; in addition, you may specify the group memberships that the token provides
Expiry
The period of time from creation after which the token will expire
Refreshable
Whether the token may be refreshed for continued use or not
Audience
The set of Artifactory instances or clusters on which the token may be used identified by their Service IDs. The Service ID is a unique, internally generated identifier of an Artifactory instance or cluster and is obtained through Get Service ID REST API endpoint.

Access tokens are fully managed through REST API as described below. 

Info
iconfalse
titlePage Contents

Table of Contents
maxLevel4
minLevel2


Cross-Instance Authentication

Access tokens support cross-instance authentication through a "circle of trust" established by sharing a private and public key pair among all participating instances. It is up to the Artifactory administrator to make sure that all participating instances are equipped with the same key pair. This means that any instance can generate a token to be used with any other instance within the circle of trust. When an Artifactory instance receives a REST API call authenticated by a signed token, it will use the root certificate that includes the public key to verify that its issuer is in the circle of trust. 

Note
titleLimitations

Only a token that is expirable and refreshable can be used for authentication on a different instance from the one that created it.

Only the issuing instance can refresh a token.

Cross instance authentication

Setting the Private Key and Root Certificate

As mentioned above, it is up to the Artifactory administrator to make sure that all participating instances are equipped with the same key pair by performing the following steps:

Artifactory Pro or OSS

  1. Start up the first Artifactory instance (or cluster node for an HA installation) that will be in your circle of trust. A private key and root certificate are generated and stored under $ARTIFACTORY_HOME/access/etc/keys.
  2. Copy the private key and root certificate files to a location on your file system that is accessible by all other instances/nodes that are in your circle of trust.

  3. Before bootstrapping, for each of the other instances/nodes, create the $ARTIFACTORY_HOME/access/etc folder and create a properties file in it called access.bootstrap.config with the following contents:

    Code Block
    key=/path/to/private.key
    crt=/path/to/root.crt
  4. When each instance/node starts up, if the $ARTIFACTORY_HOME/access/etc/access.bootstrap.config file exists, then the private key and root certificate are copied from the specified location into the server's home directory under $ARTIFACTORY_HOME/access/etc/keys.

Artifactory HA

In the case of an Artifactory HA installation, the private key and root certificate are included in the bootstrap bundle


Using Tokens

There are several ways you can use access tokens for authentication.

Basic Authentication

An access token can be used instead of a password for basic authentication. This may be useful when you need a client (such as certain dependency managers) that only supports basic authentication to access Artifactory. In this case, it is important to access Artifactory using the same user name provided when creating the token (with -d "username=<USERNAME>").

For example, to use an access token as a password to ping Artifactory you could use:

Code Block
curl -u<USERNAME>:<TOKEN> http://ARTIFACTORY_URL/api/system/ping

Authorization Headers

An access token can be used as a bearer token in authorization headers. This is especially useful for authenticating CI servers with Artifactory instead of using credentials, since you don't need to have a user defined in Artifactory if the group provided in -d "member-of-groups:<GROUP>" is configured in that Artifactory instance. As a result, there is no need to manage fictitious users for your different automation tools that need access to Artifactory. 

For example, to use an access token as a bearer token to ping Artifactory you could use:

Code Block
curl -H"Authorization: Bearer <TOKEN>" http://ARTIFACTORY_URL/api/system/ping

Support Authentication for Non-Existing Users

One of the big advantages of access tokens is the fact that you don't have to create a user in Artifactory to use them. When creating a token, you can specify a user name that does not exist, and Artifactory will create a transient user that will only exist as long as the token is valid. This can be useful to in giving access to different tools such as a CI server coordinating a build without having to manage fake user accounts. This method is also more secure since you can assign a new token for each "job" that the external tool runs.

 


Generating Expirable Tokens

You can limit the validity period of a token by setting the expiry time when generating a token. If set the token will be valid until the expiration time will pass.
You can all set a token to be non-expirable by setting the expiry to zero, in which case it will valid indefinitely until actively revoked. 

Setting this value is by using the "&expires_in=<VALUE_IN_SECONDS>" query param when generating the token (see example in REST api section below). If not used the default value will be 3600 meaning your token will be valid for one hour.


Generating Refreshable Tokens

As mentioned above, you can limit the validity period of an token by setting its expiry time. To allow extending access privileges of a token once it has expired, you can provide a refresh token which will generate a new token with the same privileges as the original one. This takes token management out of the hands of its issuer and delegates it to the user who received the token.

Note
titleWho can refresh?

Only the instance (or HA cluster) that issued a refreshable token can actually refresh it.

 


Revoking Tokens

Any can be revoked but only by instance (or cluster) that issued it. A token with an expiry specified will lapse automatically upon reaching its expiry period (but can also be actively revoked earlier). A token that is not expirable (expires_in parameter is set to 0) must be actively revoked to terminate its usage. As described above, to support cross-site authentication, a token must be both expirable and refreshable. Note that this kind of token cannot be revoked. The only way to terminate its usage is to revoke its refresh token, so its usage will be terminated next time its expiry period lapses.

Tip
title"Revoking" a cross-instance authentication token

To terminate usage of a token used for cross-instance authentication, you need to revoke its refresh token.

 


REST API

All management of access tokens is done via REST API through the endpoints described below.

Creating Tokens

Description: Creates an access token
Since: 5.0.0
Security: Requires an admin user
Usage: POST /api/security/token
Content-Type: application/x-www-form-urlencoded 

Produces: application/json

Code Block
{
   "access_token:   "<the access token>",
   "expires_in":    <Validity period in seconds>,
   "scope":         "<access scope>",
   "token_type":    "Bearer",
   "refresh_token": "<the refresh token if access_token is refreshable>"
}

Sample Usage:

Code Block
curl -uadmin:password -XPOST "http://localhost:8081/artifactory/api/security/token" -d "username=johnq" -d "scope=member-of-groups:readers"
 
200
{
   "access_token:   "adsdgbtybbeeyh...",
   "expires_in":    3600,
   "scope":         "api:* member-of-groups:readers",
   "token_type":    "Bearer",
   "refresh_token": "fgsfgsdugh8dgu9s8gy9hsg..."
}

This endpoint takes the following parameters:

grant_type

[Optional, default: "client_credentials"]

The grant to use to authenticate the request. In this case, the only value supported is "client_credentials" which is also the default value if this parameter is not specified.

username

The user name for which this token is created. If the user does not exist, a transient user is created.

If username is omitted, the member-of-groups scope token must be provided (e.g. member-of-groups: g1, g2, g3...)

scope

[Optional if the user specified in username exists]

The scope to assign to the token provided as a space-separated list of scope tokens. Currently there are two possible scope tokens:

  • "api:*" - indicates that the token grants access to REST API calls. This is always granted by default whether specified in the call or not.
  • member-of-groups:[<group-name>] - indicates that groups that the token is associated with. The token grants access according to the permission targets specified for the groups listed.

If omitted and the username specified exists, the token is granted the scope of that user.

expires_in

[Optional, default: 3600]

The time in seconds for which the token will be valid. To specify a token that never expires, set to zero.

refreshable

[Optional, default: false]

If true, this token is refreshable and the refresh token can be used to replace it with a new token once it expires.

audience

[Optional, default: Only the service ID of the Artifactory instance that created the token]

A space-separate list of the other Artifactory instances or services that should accept this token identified by their Artifactory Service IDs as obtained from the Get Service ID endpoint.

Refresh Token

Description: Refresh an access token to extend its validity. If only the access token and the refresh token are provided (and no other parameters), this pair is used for authentication. If username or any other parameter is provided, then the request must be authenticated by a token that grants admin permissions.
Since: 5.0.0
Security: Requires an admin user (unless both access token and refresh token are provided)
Usage: POST /api/security/token

Content-Type: application/x-www-form-urlencoded

Produces: application/json (Please refer to Create Tokens)

Sample Usage: 

Code Block
curl -XPOST "http://localhost:8081/artifactory/api/security/token" -d "grant_type=refresh_token" -d "refresh_token=fgsg53t3g…" -d "access_token=gsfdgw35gt..."
 
200 (Success) As in Create Token
 
400 (Error) If the token was created by a different Artifactory instance (and hence cannot be refreshed)

This endpoint takes the following parameters:

grant_type

Should be set to refresh_token.

refresh_token
The refresh token of the access token that needs to be refreshed.
access_token

[Required if username is omitted]

The access token to refresh.

username

Please refer to Create Tokens.

Note: access_token and username are mutually exclusive, so only one of these parameters should be specified.

If access_token is provided, the new token is created with the same settings as that token.

 

scope
expires_in
refreshable
audience

Revoke Token

Description: Revoke an access token 
Since: 5.0.0
Security: Requires an admin user
Usage: POST /api/security/token/revoke
Content-Type: application/x-www-form-urlencoded
token=<token>
Produces: application/json 
Sample Usage:

Code Block
curl -uadmin:password -XPOST "http://localhost:8081/artifactory/api/security/token/revoke" -d "token=fasdt3..."
 
200 OK (Also returned if the token was already revoked or non-existent)
 
400 (Error) If the token was created by a different Artifactory instance (and hence cannot be revoked)

Get Service ID

Description: Provides the service ID of an Artifactory instance or cluster
Since: 5.0.0
Security: Requires an admin user
Usage: GET /api/system/service_id
Produces: text/plain
Sample Usage:

Code Block
curl -uadmin:password -XGET "http://localhost:8081/artifactory/api/system/service_id"
 
200
jf-artifactory@ee27b1d1-534d-4723-80b5-5bd893d19c43

Troubleshooting

Expand
titleTokens are not being verified correctly and cross-site authentication is not working
Cause
An exception is thrown for "java.lang.IllegalStateException: Provided private key and latest private key fingerprints mismatch"
Symptoms

During startup, Artifactory fails to start and an error is thrown:

java.lang.IllegalStateException: Provided private key and latest private key fingerprints mismatch.

Cause

Artifactory tries to validate and compare access keys' fingerprint that reside on Artifactory's database and the local file system. If the keys do not match, the exception above will be thrown as along with the mismatching fingerprint IDs.

Scenarios:

A. When setting up your circle of trust, something has gone wrong and the different participating Artifactory installations do not share the same private key and root certificate. Causing cross-site authentication to not work due to keys validation failure.


B. During an attempted upgrade/installation of Artifactory.
Resolution

Follow the steps below to make sure that all instances in your circle of trust have the same private key and root certificate:

Warning
titleKeys rotation will invalidate any issued access tokens

The procedure below will create new key pairs which in turn will invalidate any existing Access Tokens.

  1. Copy the private key and root certificate files from the first Artifactory instance to a location on your file system that is accessible by all other instances/nodes that are in your circle of trust.

  2. Before bootstrapping, for each of the other instances/nodes:
    1. Delete the existing private key and root certificate files (private.key and root.cert) from the $ARTIFACTORY_HOME/access/etc folder.
    2. Create the $ARTIFACTORY_HOME/access/etc/access.bootstrap.config with the following contents:

      Code Block
      key=/path/to/private.key
      crt=/path/to/root.crt
    3. Add the following JVM property to $ARTIFACTORY_HOME/bin/artifactory.default:

      Code Block
      -Djfrog.access.force.replace.existing.root.keys=true
    4. Start up the new instance and verify that the startup.log file shows the following entry: 

      Code Block
      *******************************************************************
      *** Forcing replacement of the root private key and certificate ***
      *******************************************************************
    5. Delete the JVM property you added to $ARTIFACTORY_HOME/bin/artifactory.default in step c.