# API Key Management

API keys authenticate programmatic access to the Interlynk platform — from CI/CD pipelines, the `pylynk` CLI, and direct API calls. Interlynk supports two token types: **user tokens** (tied to an individual) and **service tokens** (tied to an organization).

***

## Token Types

| Property         | User Token                                      | Service Token                                                               |
| ---------------- | ----------------------------------------------- | --------------------------------------------------------------------------- |
| Bound to         | Individual user account                         | Organization                                                                |
| Permissions      | Inherits user's role                            | Assigned a specific role at creation                                        |
| Creator tracking | N/A                                             | Records who created it (`creator_id`)                                       |
| Lifecycle        | Tied to user — invalidated when user is removed | Outlives the creator — persists even if the creator leaves the organization |
| Visibility       | Visible only to the owning user                 | Admins see all; non-admins see only tokens they created                     |
| Use case         | Personal CLI/API access                         | CI/CD pipelines, automation                                                 |
| Prefix           | `lynk_live_*`                                   | `lynk_service_*`                                                            |
| Limit            | No hard limit                                   | 100 per organization                                                        |

***

## Token Creation

### When to Create Tokens

* **User tokens**: For individual developers or security engineers interacting with the API or CLI during local development.
* **Service tokens**: For CI/CD pipelines, automated SBOM uploads, scheduled jobs, or any non-interactive access.

### Required Permissions

* Creating **user tokens** requires the `manage_api_tokens` permission.
* Creating **service tokens** requires the `manage_api_tokens` permission. Any user with this permission can create service tokens and select any role available in the organization.

### Token Scopes

* **User tokens** inherit the full permission set of the user's current organization role.
* **Service tokens** are assigned a specific organization role at creation time. The creator selects the role during creation — any role in the organization can be chosen regardless of the creator's own role. Choose the most restrictive role that satisfies the token's purpose.

### Expiration Best Practices

| Environment           | Recommended Expiration |
| --------------------- | ---------------------- |
| Development           | 30 days                |
| CI/CD pipelines       | 90 days                |
| Production automation | 90–180 days            |
| Temporary/one-off     | 24 hours or 7 days     |

Tokens without an expiration date remain valid until explicitly revoked. Avoid creating non-expiring tokens for CI/CD use.

### Security Considerations

{% hint style="warning" %}
The raw token value is displayed only once at creation time. It cannot be retrieved afterward. Copy it immediately and store it in a secrets manager.
{% endhint %}

* Tokens are stored as HMAC-SHA256 digests. Interlynk cannot recover a lost token.
* All token usage is tracked with a `last_used_at` timestamp.
* Revoked or expired tokens are rejected immediately on any API call.

### Creating a User Token (UI)

1. Navigate to **Settings > Personal > Security Tokens**.
2. Click **New Token**.
3. Enter a descriptive **Token Name** (4–128 characters). Use a name that identifies the purpose, such as `ci-sbom-upload` or `local-dev`.
4. Optionally set an **Expiration Date**. Uncheck "No Expiration" to enable the date picker.
5. Click **Create**.
6. Copy the displayed token immediately. It will not be shown again.

### Creating a Service Token (UI)

1. Navigate to **Settings > Organization > Service Tokens**.
2. Click **New Service Token**.
3. Enter a **Token Name**.
4. Select a **Role** to assign to the token. This determines what the token can access.
5. Optionally set an **Expiration Date**.
6. Click **Create**.
7. Copy the displayed token immediately.

***

## Token Deletion

### Revoking Tokens

Revoking a token invalidates it immediately. Any API call or CLI command using a revoked token will receive a `401 Unauthorized` response.

**To revoke a user token:**

1. Navigate to **Settings > Personal > Security Tokens**.
2. Click the action menu on the token row.
3. Select **Revoke**.

**To delete a service token:**

1. Navigate to **Settings > Organization > Service Tokens**.
2. Click the action menu on the token row.
3. Select **Delete**.

### Impact Analysis

Before revoking a token, consider:

| Impact          | Details                                                                          |
| --------------- | -------------------------------------------------------------------------------- |
| CI/CD pipelines | Any pipeline using the token will fail on the next run                           |
| Scheduled jobs  | Automated SBOM uploads or downloads will stop                                    |
| Integrations    | Any webhook or external system authenticating with the token will lose access    |
| Other users     | Service tokens may be shared across teams — verify no other systems depend on it |

Check the token's `last_used_at` timestamp to determine if it is actively in use before revoking.

***

## Service Tokens

### User Token vs. Service Token

Use **service tokens** for any non-interactive, system-to-system access. Service tokens are bound to the organization, not the individual — they **outlive the creator**. If the team member who created a service token leaves the organization, the token continues to function with its assigned role.

Each service token tracks who created it. This enables:

* **Admins**: Full visibility — admins see all service tokens in the organization regardless of who created them, and can revoke or delete any token.
* **Non-admins**: Scoped visibility — non-admin users see only the service tokens they personally created, and can only manage their own.

Use **user tokens** only for personal, interactive use (local CLI sessions, ad hoc API calls).

### CI/CD Usage

Service tokens are the recommended authentication method for CI/CD pipelines:

```yaml
# GitHub Actions example
env:
  INTERLYNK_SECURITY_TOKEN: ${{ secrets.INTERLYNK_SERVICE_TOKEN }}

steps:
  - name: Upload SBOM
    run: pylynk upload --prod "my-app" --sbom sbom.json
```

```yaml
# GitLab CI example
variables:
  INTERLYNK_SECURITY_TOKEN: $INTERLYNK_SERVICE_TOKEN

upload_sbom:
  script:
    - pylynk upload --prod "my-app" --sbom sbom.json
```

### Least Privilege Recommendations

| Use Case                                             | Recommended Role                                           |
| ---------------------------------------------------- | ---------------------------------------------------------- |
| SBOM upload only                                     | Viewer (with upload permission) or custom upload-only role |
| SBOM upload + vulnerability review                   | Operator                                                   |
| Full automation (policy management, user management) | Admin (use sparingly)                                      |
| Read-only dashboards / reporting                     | Viewer                                                     |

Create a custom role with only the permissions required by the automation. Assign that role to the service token.

***

## Token Usage

### curl Example

Upload an SBOM using the Interlynk GraphQL API:

```bash
curl -X POST https://api.interlynk.io/lynkapi \
  -H "Authorization: Bearer $INTERLYNK_SECURITY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query { organization { projectGroups(first: 10) { totalCount nodes { id name } } } }"
  }'
```

**Successful response:**

```json
{
  "data": {
    "organization": {
      "projectGroups": {
        "totalCount": 3,
        "nodes": [
          { "id": "abc-123", "name": "my-app" }
        ]
      }
    }
  }
}
```

**Error response (invalid token):**

```json
{
  "errors": [
    { "message": "Authentication failed. Please check your token." }
  ]
}
```

### pylynk CLI Examples

**Set the API key via environment variable (recommended):**

```bash
export INTERLYNK_SECURITY_TOKEN="lynk_service_your_token_here"
```

**Upload an SBOM:**

```bash
pylynk upload --prod "my-app" --sbom ./sbom.cdx.json
```

**Upload to a specific environment:**

```bash
pylynk upload --prod "my-app" --env "production" --sbom ./sbom.cdx.json
```

**Download an enhanced SBOM:**

```bash
pylynk download --prod "my-app" --env "production" --ver "v1.2.0" \
  --out-file enhanced-sbom.json \
  --vuln true \
  --include-support-status true
```

**Download by version ID:**

```bash
pylynk download --verId "abc-123-def" --out-file sbom.json
```

**List products:**

```bash
pylynk prods --output json
```

**List vulnerabilities:**

```bash
pylynk vulns --prod "my-app" --vuln-details --vex-details --output json
```

***

## Best Practices

### Never Hardcode Tokens

Store tokens in a secrets manager or CI/CD secret store. Never commit tokens to source control.

```bash
# Correct — use environment variable
export INTERLYNK_SECURITY_TOKEN="$VAULT_SECRET"

# Incorrect — hardcoded in script
pylynk upload --token "lynk_service_abc123" --prod "my-app" --sbom sbom.json
```

### Rotation Strategy

1. Create a new token with the same role and permissions.
2. Update all systems (CI/CD pipelines, scripts, secrets managers) to use the new token.
3. Verify the new token is functioning by checking `last_used_at`.
4. Revoke the old token.

Rotate tokens on a regular schedule (every 90 days for production service tokens) and immediately if a token may have been exposed.

### Incident Response — Token Leak

If a token is leaked (committed to a public repo, logged in plaintext, exposed in a support ticket):

1. **Revoke immediately.** Navigate to the token management page and revoke or delete the token.
2. **Audit usage.** Check the token's `last_used_at` to determine if it was used after the leak.
3. **Create a replacement.** Issue a new token with the same role.
4. **Review scope.** If the leaked token had admin permissions, audit recent changes to the organization for unauthorized modifications.
5. **Rotate related secrets.** If the token was stored alongside other secrets, rotate those as well.

***

## Common Misconfigurations

| Issue                                      | Symptom                                                   | Fix                                                                                              |
| ------------------------------------------ | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| Token passed via `--token` flag in CI logs | Token visible in build logs                               | Use `INTERLYNK_SECURITY_TOKEN` env var instead                                                   |
| Service token with Admin role              | Excessive permissions for automation                      | Create a custom role with minimum required permissions                                           |
| No expiration set on service tokens        | Tokens remain valid indefinitely                          | Set 90-day expiration and rotate proactively                                                     |
| Token created by a user who left           | Token still works but the creator is no longer in the org | Admins retain full visibility and can revoke orphaned service tokens; audit during offboarding   |
| Non-admin cannot find a service token      | Non-admins only see tokens they created                   | Ask an admin to locate and manage the token, or re-create it under your own account              |
| Wrong API URL                              | `401` or connection errors                                | Verify `INTERLYNK_API_URL` is set to `https://api.interlynk.io/lynkapi` (or omit to use default) |
