API tokens
API tokens are a way to provide programmatic access to Atlan without relying on a user's own credentials or permissions.
API tokens are commonly thought to be synonymous with personal access tokens (PAT). In other words, many developers assume that an API token will have the same privileges and permissions as the user who created them. This isn't the case. API tokens are their own unique actor and carry entirely their own set of permissions, completely independent from the user who created or otherwise maintains them.
Create API token
To create a new API token:
- Java
- Python
- Kotlin
- Go
- Raw REST API
ApiToken token = ApiToken.create(client, "token-name"); // (1)
String tokenValue = token.getAttributes().getAccessToken(); // (2)
-
You can use the
ApiToken.create()method to create a new API token. Because this operation will create the token in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant. -
The actual value of the API token will only be available in this immediate response of the creation, under
.getAttributes().getAccessToken().Can't be accessed again later
You won't be able to retrieve the actual value of the API token again at a later point, for example when retrieving or updating the API token. :::
from pyatlan.client.atlan import AtlanClient
client = AtlanClient()
token = client.token.create("token-name") # (1)
token_value = token.attributes.access_token # (2)
-
You can use the
token.create()method to create a new API token. -
The actual value of the API token will only be available in this immediate response of the creation, under
.attributes.access_token.Can't be accessed again later
You won't be able to retrieve the actual value of the API token again at a later point, for example when retrieving or updating the API token. :::
val token = ApiToken.create(client, "token-name") // (1)
val tokenValue = token.attributes.accessToken // (2)
-
You can use the
ApiToken.create()method to create a new API token. Because this operation will create the token in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant. -
The actual value of the API token will only be available in this immediate response of the creation, under
.attributes.accessToken.Can't be accessed again later
You won't be able to retrieve the actual value of the API token again at a later point, for example when retrieving or updating the API token. :::
displayName := "token-name"
token, atlanErr := ctx.TokenClient.Create(&displayName, nil, nil, nil) // (1)
if atlanErr != nil {
logger.Log.Errorf("Error : %v", atlanErr)
}
tokenValue := *token.Attributes.AccessToken // (2)
-
You can use the
TokenClient.Create()method to create a new API token. -
The actual value of the API token will only be available in this immediate response of the creation, under
.Attributes.AccessToken.Can't be accessed again later
You won't be able to retrieve the actual value of the API token again at a later point, for example when retrieving or updating the API token. :::
{
"displayName": "token-name", // (1)
"description": "", // (2)
"personas": [], // (3)
"personaQualifiedNames": [], // (4)
"validitySeconds": 409968000 // (5)
}
-
You must provide a name for the token when creating it.
-
You can optionally provide a description, but even if you don't want to provide a description must send an empty string for it in the request.
-
You must always send an empty
personasarray (this is now unused, but still required). -
You can optionally list personas to link the API token with, but even if you don't send any must send an empty list. If you are linking the API token to one or more personas, use their
qualified_namein the list.Must be complete set you want linked to the API token
Any personas you leave out of the set will be removed from the API token, if they're already associated with it. (Further, if you send an empty set or no value at all for personas in the update, then ALL linked personas will be removed from the token.)
:::
5. You also need to specify how long the API token should last before automatically expiring. The value of 409968000 will be interpreted as never expiring.
Retrieve API token
You can retrieve an API token either by its name or its client ID (the name used when it's associated with some other object).
- Java
- Python
- Kotlin
- Go
- Raw REST API
ApiToken token = ApiToken.retrieveByName(client, "token-name"); // (1)
- The
retrieveByName()method handles fetching the API token based on its name. Because this operation will retrieve information from Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.
ApiToken token = client.apiTokens.getById("apikey-ac69de56-6529-4c8f-b53c-791cb5346308"); // (1)
- The
getById()method on theapiTokensmember of any client handles fetching the API token based on its client ID. This is the same as the username that will be captured when an API token is assigned to an asset without theservice-account-prefix.
from pyatlan.client.atlan import AtlanClient
client = AtlanClient()
token = client.token.get_by_name("token-name") # (1)
- The
token.get_by_name()method handles fetching the API token based on its name.
from pyatlan.client.atlan import AtlanClient
client = AtlanClient()
token = client.token.get_by_id("apikey-ac69de56-6529-4c8f-b53c-791cb5346308") # (1)
- The
token.get_by_id()method handles fetching the API token based on its client ID. This is the same as the username that will be captured when an API token is assigned to an asset without theservice-account-prefix.
val token = ApiToken.retrieveByName(client, "token-name") // (1)
- The
retrieveByName()method handles fetching the API token based on its name. Because this operation will retrieve information from Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.
val token = client.apiTokens.getById("apikey-ac69de56-6529-4c8f-b53c-791cb5346308") // (1)
- The
getById()method on theapiTokensmember of any client handles fetching the API token based on its client ID. This is the same as the username that will be captured when an API token is assigned to an asset without theservice-account-prefix.
token, atlanErr := ctx.TokenClient.GetByName("token-name") // (1)
- The
TokenClient.GetByName()method handles fetching the API token based on its name.
token, atlanErr := ctx.TokenClient.GetByID("apikey-ac69de56-6529-4c8f-b53c-791cb5346308") // (1)
- The
TokenClient.GetByID()method handles fetching the API token based on its client ID. This is the same as the username that will be captured when an API token is assigned to an asset without theservice-account-prefix.
// (1)
- The search criteria for retrieving an API token by its name is embedded as query parmeters in the request URL.
// (1)
- The search criteria for retrieving an API token by its name is embedded as query parmeters in the request URL.
Update API token
There is limited information to update on an API token:
- Java
- Python
- Kotlin
- Go
- Raw REST API
ApiToken token = ApiToken.retrieveByName(client, "token-name"); // (1)
ApiToken revised = token.toBuilder() // (2)
.attributes(token.getAttributes().toBuilder()
.description("Now with a description.") // (3)
.build())
.build();
ApiToken updated = revised.update(client); // (4)
- You are best first retrieving the API token you want to update. Because this operation will retrieve information from Atlan, you must provide it an
AtlanClientthrough which to connect to the tenant. - You can then use the builder pattern to update information within that token, such as its description.
- Note that some information, like description, is embedded within the attributes of the token.
- You can then send the revised token information to Atlan to be updated. Because this operation will persist the token in Atlan, you must provide it an
AtlanClientthrough which to connect to the tenant.
from pyatlan.client.atlan import AtlanClient
client = AtlanClient()
token = client.token.get_by_name("token-name") # (1)
client.token.update( # (2)
token.guid,
token.display_name,
description="Now with a description.",
)
- You are best first retrieving the API token you want to update.
- You can then send the revised token information to Atlan to be updated using the
token.update()method, and passing the updated information (like the new description).
val token = ApiToken.retrieveByName(client, "token-name") // (1)
val revised = token.toBuilder() // (2)
.attributes(token.attributes.toBuilder()
.description("Now with a description.") // (3)
.build())
.build()
val updated = revised.update(client) // (4)
- You are best first retrieving the API token you want to update. Because this operation will retrieve information from Atlan, you must provide it an
AtlanClientthrough which to connect to the tenant. - You can then use the builder pattern to update information within that token, such as its description.
- Note that some information, like description, is embedded within the attributes of the token.
- You can then send the revised token information to Atlan to be updated. Because this operation will persist the token in Atlan, you must provide it an
AtlanClientthrough which to connect to the tenant.
token, _ := ctx.TokenClient.GetByName("token-name") // (1)
displayName := "Updated name"
description := "Now with a description."
ctx.TokenClient.Update(token.GUID, &displayName, &description, nil) // (2)
- You are best first retrieving the API token you want to update.
- You can then send the revised token information to Atlan to be updated using the
TokenClient.Updatemethod, and passing the updated information (like the new description and display name).
{
"displayName": "token-name", // (1)
"description": "Now with a revised description.", // (2)
"personas": [], // (3)
"personaQualifiedNames": [] // (4)
}
-
You must provide the name for the token when updating it, in addition to its ID (GUID) in the request URL itself.
-
You can provide updates to its description, for example.
-
You must always send an empty
personasarray (this is now unused, but still required). -
You must also list personas to link the API token with, even if you don't send any you must send an empty list. If you do specify personas to link to the API token, use the
qualified_nameof the personas.Must be complete set you want linked to the API token
Any personas you leave out of the set will be removed from the API token, if they're already associated with it. (Further, if you send an empty set or no value at all for personas in the update, then ALL linked personas will be removed from the token.)
:::
Delete API token
You can delete an API token by its GUID:
- Java
- Python
- Kotlin
- Go
- Raw REST API
ApiToken.delete(client, "98fb61da-eb8f-455e-b5ea-c022ee390044"); // (1)
-
Note that the GUID of an API token isn't the same as its client ID. From an API token object, the
getId()method will give you its GUID. Because this operation will remove the token from Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.Irreversible
Once deleted, the API token will be permanently removed and no longer usable. :::
from pyatlan.client.atlan import AtlanClient
client = AtlanClient()
token = client.token.purge("98fb61da-eb8f-455e-b5ea-c022ee390044") # (1)
-
Note that the GUID of an API token isn't the same as its client ID. From an API token object, the
guidproperty will give you its GUID.Irreversible
Once deleted, the API token will be permanently removed and no longer usable. :::
ApiToken.delete(client, "98fb61da-eb8f-455e-b5ea-c022ee390044") // (1)
-
Note that the GUID of an API token isn't the same as its client ID. From an API token object, the
getId()method will give you its GUID. Because this operation will remove the token from Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.Irreversible
Once deleted, the API token will be permanently removed and no longer usable. :::
ctx.TokenClient.Purge("a853f1d5-f1f4-4cdb-b86d-c61df3ecade6") // (1)
-
Note that the GUID of an API token isn't the same as its client ID. From an API token object, the
guidproperty will give you its GUID.Irreversible
Once deleted, the API token will be permanently removed and no longer usable. :::
// (1)
-
The criteria for deleting an API token is entirely contained in the request URL. Note that the GUID of an API token isn't the same as its client ID. From an API token response, the
idproperty will give you its GUID.Irreversible
Once deleted, the API token will be permanently removed and no longer usable. :::
Give permissions to API token
As called out at the top of this page, API tokens are unique actors with their own privileges and permissions. For an API token to be able to interact with certain objects, they must be granted such permissions directly.
Link API token to persona
You can link an API token to a persona to give the API token all of the permissions granted by the policies within that persona.
- Java
- Python
- Kotlin
- Go
- Raw REST API
client.apiTokens.update( // (1)
"98fb61da-eb8f-455e-b5ea-c022ee390044", // (2)
"token-name",
null,
Set.of("default/aQi5KHtGwZYvxGnTSAYO8J")); // (3)
-
Use the
update()method on theapiTokensmember of any client to link an API token with personas. -
You will need to provide both the GUID and the display name for the API token.
-
You must also provide the complete set of personas that should be linked to the API token, using their
qualifiedNames.Must be complete set you want linked to the API token
Any personas you leave out of the set will be removed from the API token, if they're already associated with it. (Further, if you send an empty set or no value at all for personas in the update, then ALL linked personas will be removed from the token.)
:::
from pyatlan.client.atlan import AtlanClient
client = AtlanClient()
client.token.update( # (1)
guid="98fb61da-eb8f-455e-b5ea-c022ee390044", # (2)
display_name="token-name",
personas={"default/aQi5KHtGwZYvxGnTSAYO8J"}, # (3)
)
-
Use
token.update()to link an API token with personas. -
You will need to provide both the GUID and the display name for the API token.
-
You must also provide the complete set of personas that should be linked to the API token, using their
qualified_names.Must be complete set you want linked to the API token
Any personas you leave out of the set will be removed from the API token, if they're already associated with it. (Further, if you send an empty set or no value at all for personas in the update, then ALL linked personas will be removed from the token.)
:::
client.apiTokens.update( // (1)
"98fb61da-eb8f-455e-b5ea-c022ee390044", // (2)
"token-name",
null,
setOf("default/aQi5KHtGwZYvxGnTSAYO8J")) // (3)
-
Use the
update()method on theapiTokensmember of any client to link an API token with personas. -
You will need to provide both the GUID and the display name for the API token.
-
You must also provide the complete set of personas that should be linked to the API token, using their
qualifiedNames.Must be complete set you want linked to the API token
Any personas you leave out of the set will be removed from the API token, if they're already associated with it. (Further, if you send an empty set or no value at all for personas in the update, then ALL linked personas will be removed from the token.)
:::
displayName := "token-name"
tokenGUID := "98fb61da-eb8f-455e-b5ea-c022ee390044"
ctx.TokenClient.Update( // (1)
&tokenGUID, // (2)
&displayName,
nil,
[]string{"default/aQi5KHtGwZYvxGnTSAYO8J"}, // (3)
)
-
Use
TokenClient.Updateto link an API token with personas. -
You will need to provide both the GUID and the display name for the API token.
-
You must also provide the complete set of personas that should be linked to the API token, using their
qualifiedNames.Must be complete set you want linked to the API token
Any personas you leave out of the set will be removed from the API token, if they're already associated with it. (Further, if you send an empty set or no value at all for personas in the update, then ALL linked personas will be removed from the token.)
:::
{
"displayName": "token-name", // (1)
"description": "", // (2)
"personas": [], // (3)
"personaQualifiedNames": ["default/aQi5KHtGwZYvxGnTSAYO8J"] // (4)
}
-
You must provide the name for the token when updating it, in addition to its ID (GUID) in the request URL itself.
-
You must provide the description for the token. Even if you don't want it to have any description, you need to send an empty string.
-
You must always send an empty
personasarray (this is now unused, but still required). -
You must also provide the complete set of personas that should be linked to the API token, using their
qualified_names.Must be complete set you want linked to the API token
Any personas you leave out of the set will be removed from the API token, if they're already associated with it. (Further, if you send an empty set or no value at all for personas in the update, then ALL linked personas will be removed from the token.)
:::
Add API token as connection admin
For any actor to manage policies for a connection, that actor must be a connection admin on the connection. You must therefore add the API token as a connection admin to any connection you want it to be able to manage policies for.1
To carry out this operation, you must first obtain a user's bearer token. Specifically, you must obtain the bearer token for a user who is already a connection admin on the connection.
- Java
- Python
- Kotlin
- Raw REST API
List<Connection> connections = Connection.findByName(
client,
"development",
AtlanConnectorType.BIGQUERY);
Connection connection = connections.get(0); // (1)
String impersonationToken = "eyNnCJd2T9Y8fEsbdx..."; // (2)
AssetMutationResponse response = connection.addApiTokenAsAdmin(client, impersonationToken); // (3)
-
You will need to start by retrieving the connection you want to add the API token to as a connection admin. In this example, we use a search to retrieve the connection.
-
You must use a user's bearer token as an impersonation token. (We would recommend capturing this in something like an environment variable rather than embedding directly in the code.)
-
You can use the
.addApiTokenAsAdmin()method to add the API token as a connection admin. Because this operation will update the connection in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.Will add the API token, not impersonation token, as connection admin
Note that you are providing a user's bearer token as the impersonationToken only to give sufficient privileges to add the API token configured for the SDK as a connection admin. It's the API token configured for the SDK that you're adding as connection admin, not the user's bearer token. (The user's bearer token must already have connection admin permissions on this connection for the operation to succeed.)
:::
from pyatlan.client.atlan import AtlanClient
connections = client.asset.find_connections_by_name(
"development", AtlanConnectorType.BIGQUERY
)
connection = connections[0] # (1)
impersonation_token = "eyNnCJd2T9Y8fEsbdx..." # (2)
response = client.user.add_as_admin( # (3)
asset_guid=connection.guid,
impersonation_token=impersonation_token,
)
-
You will need to start by retrieving the connection you want to add the API token to as a connection admin. In this example, we use a search to retrieve the connection.
-
You must use a user's bearer token as an impersonation token. (We would recommend capturing this in something like an environment variable rather than embedding directly in the code.)
-
You can use the
user.add_as_admin()method to add the API token as a connection admin, providing the GUID of the connection and the impersonation token.Will add the API token, not impersonation token, as connection admin
Note that you are providing a user's bearer token as the impersonation_token only to give sufficient privileges to add the API token configured for the SDK as a connection admin. It's the API token configured for the SDK that you're adding as connection admin, not the user's bearer token. (The user's bearer token must already have connection admin permissions on this connection for the operation to succeed.)
:::
val connections = Connection.findByName(
client,
"development",
AtlanConnectorType.BIGQUERY)
val connection = connections[0] // (1)
val impersonationToken = "eyNnCJd2T9Y8fEsbdx..." // (2)
val response = connection.addApiTokenAsAdmin(client, impersonationToken) // (3)
-
You will need to start by retrieving the connection you want to add the API token to as a connection admin. In this example, we use a search to retrieve the connection.
-
You must use a user's bearer token as an impersonation token. (We would recommend capturing this in something like an environment variable rather than embedding directly in the code.)
-
You can use the
.addApiTokenAsAdmin()method to add the API token as a connection admin. Because this operation will update the connection in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.Will add the API token, not impersonation token, as connection admin
Note that you are providing a user's bearer token as the impersonationToken only to give sufficient privileges to add the API token configured for the SDK as a connection admin. It's the API token configured for the SDK that you're adding as connection admin, not the user's bearer token. (The user's bearer token must already have connection admin permissions on this connection for the operation to succeed.)
:::
We don't recommend attempting this change through the Raw REST APIs as it requires a number of different API calls, carefully parsing the responses and combining elements, and has high potential for minor typos or copy/paste errors to cause mistakes.
Add API token as collection editor
As with connections, if you want an API token to be able to manage a query collection or the queries within it, you must add the API token as an editor on the collection.
To carry out this operation, you must first obtain a user's bearer token. Specifically, you must obtain the bearer token for a user who is already an editor on (or owner of) the query collection.
- Java
- Python
- Kotlin
- Raw REST API
List<AtlanCollection> collections = AtlanCollection.findByName(
client,
"My query collection");
AtlanCollection collection = collections.get(0); // (1)
String impersonationToken = "eyNnCJd2T9Y8fEsbdx..."; // (2)
AssetMutationResponse response = collection.addApiTokenAsAdmin(client, impersonationToken); // (3)
-
You will need to start by retrieving the query collection you want to add the API token to as an editor. In this example, we use a search to retrieve the collection.
-
You must use a user's bearer token as an impersonation token. (We would recommend capturing this in something like an environment variable rather than embedding directly in the code.)
-
You can use the
.addApiTokenAsAdmin()method to add the API token as a collection editor. Because this operation will update the collection in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.Will add the API token, not impersonation token, as collection editor
Note that you are providing a user's bearer token as the impersonationToken only to give sufficient privileges to add the API token configured for the SDK as a collection editor. It's the API token configured for the SDK that you're adding as collection editor, not the user's bearer token. (The user's bearer token must already have collection editor permissions on this collection for the operation to succeed.)
:::
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import Collection
from pyatlan.model.fluent_search import FluentSearch
request = (
FluentSearch()
.where(FluentSearch.asset_type(Collection))
.where(Collection.NAME.eq("My query collection"))
).to_request()
response = client.asset.search(request)
collection = response.current_page()[0] # (1)
impersonation_token = "eyNnCJd2T9Y8fEsbdx..." # (2)
response = client.user.add_as_admin( # (3)
asset_guid=collection.guid,
impersonation_token=impersonation_token,
)
-
You will need to start by retrieving the query collection you want to add the API token to as a collection editor. In this example, we use a search to retrieve the collection.
-
You must use a user's bearer token as an impersonation token. (We would recommend capturing this in something like an environment variable rather than embedding directly in the code.)
-
You can use the
user.add_as_admin()method to add the API token as a collection editor, providing the GUID of the collection and the impersonation token.Will add the API token, not impersonation token, as collection editor
Note that you are providing a user's bearer token as the impersonation_token only to give sufficient privileges to add the API token configured for the SDK as a collection editor. It's the API token configured for the SDK that you're adding as collection editor, not the user's bearer token. (The user's bearer token must already have collection editor permissions on this collection for the operation to succeed.)
:::
val collections = AtlanCollection.findByName(
client,
"My query collection")
val collection = collections[0] // (1)
val impersonationToken = "eyNnCJd2T9Y8fEsbdx..." // (2)
val response = collection.addApiTokenAsAdmin(client, impersonationToken) // (3)
-
You will need to start by retrieving the query collection you want to add the API token to as an editor. In this example, we use a search to retrieve the collection.
-
You must use a user's bearer token as an impersonation token. (We would recommend capturing this in something like an environment variable rather than embedding directly in the code.)
-
You can use the
.addApiTokenAsAdmin()method to add the API token as a collection editor. Because this operation will update the collection in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.Will add the API token, not impersonation token, as collection editor
Note that you are providing a user's bearer token as the impersonationToken only to give sufficient privileges to add the API token configured for the SDK as a collection editor. It's the API token configured for the SDK that you're adding as collection editor, not the user's bearer token. (The user's bearer token must already have collection editor permissions on this collection for the operation to succeed.)
:::
We don't recommend attempting this change through the Raw REST APIs as it requires a number of different API calls, carefully parsing the responses and combining elements, and has high potential for minor typos or copy/paste errors to cause mistakes.
Add API token as collection viewer
Alternatively, if you only want the API token to be able to view and run queries within a collection (but not change them), you can add the API token as a viewer on the collection.
To carry out this operation, you must first obtain a user's bearer token. Specifically, you must obtain the bearer token for a user who is already an editor on (or owner of) the query collection.
- Java
- Python
- Kotlin
- Raw REST API
List<AtlanCollection> collections = AtlanCollection.findByName(
client,
"My query collection");
AtlanCollection collection = collections.get(0); // (1)
String impersonationToken = "eyNnCJd2T9Y8fEsbdx..."; // (2)
AssetMutationResponse response = collection.addApiTokenAsViewer(client, impersonationToken); // (3)
-
You will need to start by retrieving the query collection you want to add the API token to as an viewer. In this example, we use a search to retrieve the collection.
-
You must use a user's bearer token as an impersonation token. (We would recommend capturing this in something like an environment variable rather than embedding directly in the code.)
-
You can use the
.addApiTokenAsViewer()method to add the API token as a collection viewer. Because this operation will update the collection in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.Will add the API token, not impersonation token, as collection viewer
Note that you are providing a user's bearer token as the impersonationToken only to give sufficient privileges to add the API token configured for the SDK as a collection viewer. It's the API token configured for the SDK that you're adding as collection viewer, not the user's bearer token. (The user's bearer token must already have collection editor permissions on this collection for the operation to succeed.)
:::
from pyatlan.client.atlan import AtlanClient
from pyatlan.model.assets import Collection
from pyatlan.model.fluent_search import FluentSearch
request = (
FluentSearch()
.where(FluentSearch.asset_type(Collection))
.where(Collection.NAME.eq("My query collection"))
).to_request()
response = client.asset.search(request)
collection = response.current_page()[0] # (1)
impersonation_token = "eyNnCJd2T9Y8fEsbdx..." # (2)
response = client.user.add_as_viewer( # (3)
asset_guid=collection.guid,
impersonation_token=impersonation_token,
)
-
You will need to start by retrieving the query collection you want to add the API token to as a collection viewer. In this example, we use a search to retrieve the collection.
-
You must use a user's bearer token as an impersonation token. (We would recommend capturing this in something like an environment variable rather than embedding directly in the code.)
-
You can use the
user.add_as_admin()method to add the API token as a collection viewer, providing the GUID of the collection and the impersonation token.Will add the API token, not impersonation token, as collection viewer
Note that you are providing a user's bearer token as the impersonation_token only to give sufficient privileges to add the API token configured for the SDK as a collection viewer. It's the API token configured for the SDK that you're adding as collection viewer, not the user's bearer token. (The user's bearer token must already have collection editor permissions on this collection for the operation to succeed.)
:::
val collections = AtlanCollection.findByName(
client,
"My query collection")
val collection = collections[0] // (1)
val impersonationToken = "eyNnCJd2T9Y8fEsbdx..." // (2)
val response = collection.addApiTokenAsViewer(client, impersonationToken) // (3)
-
You will need to start by retrieving the query collection you want to add the API token to as an viewer. In this example, we use a search to retrieve the collection.
-
You must use a user's bearer token as an impersonation token. (We would recommend capturing this in something like an environment variable rather than embedding directly in the code.)
-
You can use the
.addApiTokenAsViewer()method to add the API token as a collection viewer. Because this operation will update the collection in Atlan, you must provide it anAtlanClientthrough which to connect to the tenant.Will add the API token, not impersonation token, as collection viewer
Note that you are providing a user's bearer token as the impersonationToken only to give sufficient privileges to add the API token configured for the SDK as a collection viewer. It's the API token configured for the SDK that you're adding as collection viewer, not the user's bearer token. (The user's bearer token must already have collection editor permissions on this collection for the operation to succeed.)
:::
We don't recommend attempting this change through the Raw REST APIs as it requires a number of different API calls, carefully parsing the responses and combining elements, and has high potential for minor typos or copy/paste errors to cause mistakes.
Obtain user's bearer token
For a few of the operations above, there is a bit of a "catch-22". For example:
- An API token can't manage policies for a connection if it'sn't the connection admin.
- An API token can't be used to add itself as a connection admin.2
- So how do you get an API token set up as a connection admin, without using an API token?
The answer is that you must use a user's own bearer token (temporarily)—specifically a user who already has the appropriate authority on the object. (In this example, a user who is already a connection admin on that connection.)
To do this, you'll need to3:
- Log in to Atlan as the user with the level of access required (for example, the user who is a connection admin).
- Open the Developer Tools view of Chrome:
- Open the View menu,
- then Developer,
- then Developer Tools.
- Leave the Developer Tools window open, but change back to your original Atlan window.
- Navigate to the Assets page where you can discover assets.
- Return to the Developer Tools window and find any indexsearch item along the left:
- Right-click the indexsearch item,
- then Copy,
- then Copy as cURL.
Paste what this has copied into a text editor:4
curl 'https://tenant.atlan.com/api/meta/search/indexsearch' \
-H 'authority: tenant.atlan.com' \
-H 'accept: application/json, text/plain, */*' \
-H 'accept-language: en-GB,en-US;q=0.9,en;q=0.8' \
-H 'authorization: Bearer eyNnCJd2T9Y8fEsbdxTgKQqyWFm7uNBvw55EjAIakh9Yrg3cdd1YoNMXr1LtFmreHfVrYrSRxCzUYcoJKASXovfBO5PnGZOWe8hAdxb7WqesNZS.TPFcWzwRLA2Aeb38iWBIAG3rrsTz7iyufecbPeLBLTZ2RjaweLji7PGIVz5Mj8G2bAIPM7tguCGbz...' \
-H 'content-type: application/json' \
...
The details you need are on the highligted line 5, that begins with -H 'authorization: Bearer. You specifically want everything after the word Bearer, up to the final single quote (') at the end of the line. So in this example you would copy:
eyNnCJd2T9Y8fEsbdxTgKQqyWFm7uNBvw55EjAIakh9Yrg3cdd1YoNMXr1LtFmreHfVrYrSRxCzUYcoJKASXovfBO5PnGZOWe8hAdxb7WqesNZS.TPFcWzwRLA2Aeb38iWBIAG3rrsTz7iyufecbPeLBLTZ2RjaweLji7PGIVz5Mj8G2bAIPM7tguCGbz...
This is the user's own bearer token.
Be aware that the user's own bearer token will have a limited lifespan. At some point the user will be automatically logged out and will be asked to log in again, at which point this bearer token will have expired and need to be re-retrieved.