---
title: "Create an agent with its own identity"
canonical: https://workspace.socra.com/docs/admin/agents/create-an-agent
---

# Create an agent with its own identity

Create an Account identity for an agent and configure its runtime to make Socra requests as that identity.

The installation creates an Account member with `type: app` and role `member`. In Admin, this identity appears under **Directory → Installed apps**. This procedure configures identity and authentication for a runtime you provide.

## Before you start

A human with the Account role **owner** or **admin** can approve the installation. The setup session must also have permission to create and configure the Cloud Project.

Setup uses the approving human's Account session. After installation, the runtime needs only the client ID, client secret, and principal ID to obtain tokens. Credential storage and runtime configuration remain your choice.

Replace uppercase placeholders in the commands with the values you receive. This guide creates the Project and installation in the current Account.

## Prepare authentication

Choose CLI or cURL. The selection applies to all operations on this page. Setup and revocation use the approving human's credentials; token exchange uses the installed principal's client credentials.

### CLI

If you need the CLI, follow the [CLI installation guide](/docs/cortex/reference/cli#install-the-cli).

Install the Account plugin:

```bash
socra install account
```

Check the current session:

```bash
socra account status
```

If you aren't signed in, run:

```bash
socra account login
```

Complete sign-in and select the intended Account. Continue with the current Account if it is already correct. Use `socra account switch` only if you need a different Account.

Install the setup plugins:

```bash
socra install project oauth
```

### cURL

Supply `HUMAN_ACCESS_TOKEN`: an existing Account-scoped OAuth access token for the human approving setup. Obtain it through your existing [Account OAuth sign-in integration](https://cloud.socra.com/docs/oauth). A global ID token or the new app's token cannot replace it for installation consent.

Check which Account member the token represents:

```bash
curl --fail-with-body --request POST https://account.socra.cloud/directory/v1/users/me \
  --header "Authorization: Bearer HUMAN_ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{}'
```

Confirm the intended Account in your sign-in integration and that this member has role `owner` or `admin`. cURL does not use or switch the CLI's active profile. If you do not have a human Account token, use the CLI setup path.

## Create the Project

Choose an unused `PROJECT_SLUG`, such as `company-tpm`:

### CLI

```bash
socra project create PROJECT_SLUG
```

### cURL

```bash
curl --fail-with-body --request POST https://project.socra.cloud/v1/projects \
  --header "Authorization: Bearer HUMAN_ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{"slug":"PROJECT_SLUG"}'
```

Record the returned `proj_...` ID as `PROJECT_ID`. The [Cloud Project](https://cloud.socra.com/docs/project) identifies the application and attributes its service usage.

Set the display name before installing the identity:

### CLI

```bash
socra oauth config set PROJECT_ID --name "Company TPM" --audience internal
```

### cURL

```bash
curl --fail-with-body --request PATCH https://oauth.socra.cloud/v1/projects/PROJECT_ID/config \
  --header "Authorization: Bearer HUMAN_ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{"application_name":"Company TPM","audience":"internal"}'
```

The `internal` audience limits installation to the Project's Account. See [OAuth documentation](https://cloud.socra.com/docs/oauth) for installations into another Account.

## Create the client and credentials

Register a confidential client:

### CLI

```bash
socra oauth client create "Company TPM runtime" --project PROJECT_ID --type web
```

### cURL

```bash
curl --fail-with-body --request POST https://oauth.socra.cloud/v1/projects/PROJECT_ID/clients \
  --header "Authorization: Bearer HUMAN_ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{"name":"Company TPM runtime","type":"web","redirect_uris":[],"javascript_origins":[]}'
```

Record the returned `client_...` ID as `CLIENT_ID`. The `web` type supports client secrets. This flow requires no website or redirect URI.

Create a secret:

### CLI

```bash
socra oauth client-secret create CLIENT_ID --project PROJECT_ID
```

### cURL

```bash
curl --fail-with-body --request POST https://oauth.socra.cloud/v1/projects/PROJECT_ID/clients/CLIENT_ID/secrets \
  --header "Authorization: Bearer HUMAN_ACCESS_TOKEN"
```

The response includes the secret ID and a `secret` value shown only once. Retain the value using your runtime's credential mechanism, and record the ID as `SECRET_ID` for revocation. Capture the credential without repeating it in chat.

## Install the identity

Using an owner or admin session, run:

### CLI

```bash
socra oauth installation create --project PROJECT_ID
```

### cURL

```bash
curl --fail-with-body --request POST https://oauth.socra.cloud/v1/installations \
  --header "Authorization: Bearer HUMAN_ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{"project_id":"PROJECT_ID","scopes":[]}'
```

This operation records admin consent and creates the Account-local principal. Confirm that `status` is `active`. Record `id` as `INSTALLATION_ID` and `principal_id` as `PRINCIPAL_ID`.

The new principal has role `member`; it does not inherit the approving human's role. This example requests no OAuth scopes. Account and resource permissions still apply. Services that require scopes need those scopes approved during installation; see the [OAuth reference](https://cloud.socra.com/docs/oauth/reference/cli).

## Obtain a token

Exchange the client credentials for an installed-principal token. Use the raw UUID returned in `principal_id` as `PRINCIPAL_ID`, rather than a Directory ID starting with `user_`.

### CLI

```bash
socra oauth token create --client CLIENT_ID --principal PRINCIPAL_ID \
  --client-secret-file CLIENT_SECRET_FILE
```

`CLIENT_SECRET_FILE` is a path you supply containing only the secret value. This is the CLI's input format; it does not determine how your runtime stores credentials.

### cURL

```bash
curl --fail-with-body --request POST https://oauth.socra.cloud/oauth/token \
  --data-urlencode "grant_type=client_credentials" \
  --data-urlencode "client_id=CLIENT_ID" \
  --data-urlencode "client_secret=CLIENT_SECRET" \
  --data-urlencode "principal_id=PRINCIPAL_ID"
```

`CLIENT_SECRET` is the secret value returned at creation. Supply it through your request mechanism without repeating it in chat. No human Bearer token is needed for this exchange.

Both methods require no human login and return JSON containing `access_token`, `token_type`, `expires_in`, and `scope`. Have your runtime capture this response. Token creation does not change the CLI's active Account profile.

## Verify the identity

Send the returned token to the Directory API. Replace `ACCESS_TOKEN` below with the token through your HTTP client's credential handling:

### CLI

The CLI does not currently accept the newly issued token for `socra directory me`; that command uses its active profile. Use the cURL tab to verify this specific app token.

### cURL

```bash
curl --fail-with-body --request POST https://account.socra.cloud/directory/v1/users/me \
  --header "Authorization: Bearer ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{}'
```

The response must identify your new principal with `type: app`, `role: member`, and the configured `display_name`. Its Directory `id` starts with `user_` and is used when granting access to that member.

## Connect your runtime

Perform the token exchange through your HTTP client or invoke the CLI command as a subprocess and parse its JSON output. Send the access token as a Bearer token on Socra API requests. Obtain another token before the returned `expires_in` interval elapses. Repeat the same client-credentials exchange; this flow provides no refresh token.

A runtime that uses an OAuth library can perform the equivalent exchange at `https://oauth.socra.cloud/oauth/token` with `grant_type=client_credentials`, `client_id`, `client_secret`, and `principal_id`. Choose the mechanism that fits your runtime.

Authentication establishes the identity. Each product still checks permissions. For a Cortex agent, use the [Cortex API reference](/docs/cortex/reference/api) and [access and permissions guide](/docs/cortex/administration/access-and-permissions). Cloud resources also require the applicable [IAM permissions](https://cloud.socra.com/docs/iam) and [service enablement](https://cloud.socra.com/docs/service).

Verify a request in an environment without the approving human's Account session. Record the app's Directory ID and the resource access granted to it.

## Troubleshoot

- **Installation is denied:** Check that the caller is a human owner or admin and the Project belongs to the selected Account when using `internal` audience.
- **Installation is pending:** Repeat the same installation command to resume provisioning. Only an active installation can issue tokens.
- **Token exchange fails:** Check the client ID, secret value, raw principal UUID, and installation status. An owner or admin can inspect the installation below.
- **A product returns 403:** Check that product's permissions and access requirements.
- **An existing token returns 401:** Obtain another token. If the exchange fails too, check for revoked credentials or installation.

### Inspect the installation

Use the approving human's Account credentials:

#### CLI

```bash
socra oauth installation get INSTALLATION_ID
```

#### cURL

```bash
curl --fail-with-body --request GET https://oauth.socra.cloud/v1/installations/INSTALLATION_ID \
  --header "Authorization: Bearer HUMAN_ACCESS_TOKEN"
```

## Revoke access

As a human owner or admin in the installation's Account, run:

### CLI

```bash
socra oauth installation delete INSTALLATION_ID
```

### cURL

```bash
curl --fail-with-body --request DELETE https://oauth.socra.cloud/v1/installations/INSTALLATION_ID \
  --header "Authorization: Bearer HUMAN_ACCESS_TOKEN"
```

This revokes installation authority and deactivates the principal. Existing tokens fail subsequent authorization checks after any resource-server introspection cache expires. Reinstalling creates a new principal and does not revive old tokens.

If the client secret is no longer needed, revoke it too:

### CLI

```bash
socra oauth client-secret delete CLIENT_ID SECRET_ID --project PROJECT_ID
```

### cURL

```bash
curl --fail-with-body --request DELETE https://oauth.socra.cloud/v1/projects/PROJECT_ID/clients/CLIENT_ID/secrets/SECRET_ID \
  --header "Authorization: Bearer HUMAN_ACCESS_TOKEN"
```
