# App Launch Tokens

## What Are App Launch Tokens?

App Launch Tokens let you **pass the authenticated user's identity to your game** when the Login System is enabled.\
The launcher generates a short-lived, single-use token and injects it into the launch arguments — your game's backend verifies it via API to get the user's identity.

{% hint style="info" %}
Requires the **Login System** addon to be enabled on your app.
{% endhint %}

***

## How It Works

{% code fullWidth="true" %}

```
┌───────────┐     ┌───────────────┐     ┌──────────────┐     ┌──────────────┐
│ Launcher  │────>│ GLC Backend   │     │  Your Game   │────>│ GLC Backend  │
│ (Desktop) │     │ /generate     │     │              │     │ /verify      │
└───────────┘     └───────────────┘     └──────────────┘     └──────────────┘
  1. Request        2. Returns           3. Game reads       4. Exchange
     token             token                args at start       token for
                       (60s TTL)                                user info
```

{% endcode %}

1. **Launcher requests a token** — Calls the GLC API with the user's session
2. **GLC returns an opaque token** — 60-second TTL, single-use
3. **Launcher injects token into launch arguments** — Replaces `{{auth_token}}` placeholder
4. **Game starts and reads the CLI arguments** — Extracts the token
5. **Game's backend calls the verify endpoint** — Exchanges the token for user identity
6. **Token is consumed** — Cannot be reused

***

## Available Placeholders

Configure these in **App Settings → Platforms → Launch Arguments**:

| Placeholder             | Replaced With                         |
| ----------------------- | ------------------------------------- |
| `{{auth_token}}`        | Short-lived opaque token (60s, 1-use) |
| `{{user_id}}`           | User's unique ID                      |
| `{{user_email}}`        | User's email address                  |
| `{{user_display_name}}` | User's display name                   |
| `{{instance_id}}`       | Instance number (multi-instance only) |

**Example launch arguments:**

```
--auth-token {{auth_token}} --user {{user_id}}
```

Your game receives:

```
--auth-token abc123def456... --user 8f14e45f-ceea-367f-a27f-c790a516bae0
```

{% hint style="warning" %}
`{{auth_token}}` is the only secure placeholder. The others (`{{user_id}}`, `{{user_email}}`, `{{user_display_name}}`) are passed as plain text and **should not be trusted without verification**. Always verify the token server-side.
{% endhint %}

***

## Security Properties

| Property    | Value                                       |
| ----------- | ------------------------------------------- |
| **TTL**     | 60 seconds                                  |
| **Usage**   | Single-use (consumed on first verification) |
| **Scope**   | Identity only — no access to GLC API        |
| **Format**  | URL-safe Base64 (64 chars)                  |
| **Cleanup** | Expired tokens are purged every 10 minutes  |

{% hint style="success" %}
Even if a token is visible in the process arguments, it's **useless after 60 seconds** and cannot be reused.
{% endhint %}

***

## API Reference

### Verify Token

Called by **your game's backend** to validate a token and get the user's identity.

```
POST /api/auth/app-launch-token/verify
```

{% hint style="success" %}
**Public endpoint** — no authentication required.
{% endhint %}

**Body:**

```json
{
  "token": "abc123def456...",
  "launcherId": 42
}
```

**Success Response:**

```json
{
  "result": {
    "valid": true,
    "userId": "8f14e45f-ceea-367f-a27f-c790a516bae0",
    "email": "player@example.com",
    "displayName": "PlayerOne"
  }
}
```

**Failure Responses:**

```json
{
  "result": {
    "valid": false,
    "reason": "Token not found."
  }
}
```

```json
{
  "result": {
    "valid": false,
    "reason": "Token already consumed."
  }
}
```

```json
{
  "result": {
    "valid": false,
    "reason": "Token expired."
  }
}
```

***

## Integration Example

### Your Game (Client Side)

Read the token from command-line arguments at startup and send it to your backend:

```csharp
// Unity C# example
string[] args = System.Environment.GetCommandLineArgs();
int tokenIndex = System.Array.IndexOf(args, "--auth-token");
if (tokenIndex >= 0 && tokenIndex + 1 < args.Length)
{
    string token = args[tokenIndex + 1];
    // Send token to your server for verification
    StartCoroutine(VerifyToken(token));
}
```

### Your Game Server (Backend)

Exchange the token for user identity:

```python
# Python example
import requests

response = requests.post(
    "https://api.gamelauncher.cloud/api/auth/app-launch-token/verify",
    json={
        "token": token_from_client,
        "launcherId": 42  # Your launcher ID
    }
)

data = response.json()["result"]
if data["valid"]:
    user_id = data["userId"]
    email = data["email"]
    # Authenticated — create game session
```

***

## Setup

1. Enable the **Login System** addon on your app
2. Go to **App Settings → Platforms → Launch Arguments**
3. Enable **Custom Launch Arguments**
4. Add placeholders: `--auth-token {{auth_token}} --user-id {{user_id}}`
5. Build and deploy your launcher
6. Implement the `/verify` call in your game's backend

{% hint style="info" %}
When the Login System is enabled, the available auth placeholders are shown as a hint below the Launch Arguments field.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gamelauncher.cloud/help/add-ons/login-system/app-launch-tokens.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
