Skip to content

Personal Access Tokens

Personal Access Tokens (PATs) provide secure API access for users to integrate with the Manager programmatically without using their primary credentials.

Overview

PATs are user-scoped tokens that allow:

  • API Authentication - Access GraphQL and REST APIs programmatically
  • Script Automation - Automate workflows with CLI tools or scripts
  • CI/CD Integration - Deploy and manage resources from CI/CD pipelines
  • Third-party Tools - Integrate with external tools and services

Security Features

PBKDF2 Hashing

PATs are hashed using PBKDF2 (Password-Based Key Derivation Function 2) following OWASP 2023 recommendations:

  • 600,000 iterations - Computational cost to prevent brute-force attacks
  • SHA-256 hash function
  • Unique salt per token
  • Only the hash is stored - plaintext token never persisted

Token Prefix

The first few characters of each token are stored for searchability without compromising security. This allows you to identify tokens in the UI without exposing the full value.

Example: pfy_abc123... → Prefix pfy_abc is searchable

Creating a Personal Access Token

Via UI

  1. Navigate to SettingsPersonal Access Tokens
  2. Click Create Token
  3. Fill in token details:
    • Name - Descriptive name (e.g., "GitHub Actions", "CLI Tool")
    • Expires At - Optional expiration date
  4. Click Create
  5. Copy the token immediately - it will only be shown once

IMPORTANT

The token is displayed only once during creation. Store it securely - you cannot retrieve it later.

Via API

graphql
mutation {
  createPersonalAccessToken(
    name: "GitHub Actions Deployment"
    expiresAt: "2025-12-31T23:59:59Z"
  ) {
    token
    personalAccessToken {
      id
      name
      createdAt
      expiresAt
    }
  }
}

Response:

json
{
  "data": {
    "createPersonalAccessToken": {
      "token": "pfy_abc123def456ghi789...",
      "personalAccessToken": {
        "id": "uuid",
        "name": "GitHub Actions Deployment",
        "createdAt": "2025-12-01T10:00:00Z",
        "expiresAt": "2025-12-31T23:59:59Z"
      }
    }
  }
}

Using Personal Access Tokens

HTTP Authentication

Include the token in the Authorization header:

bash
curl -H "Authorization: Bearer pfy_abc123def456ghi789..." \
  https://manager.example.com/query

GraphQL Client

javascript
import { createClient } from "@urql/core";

const client = createClient({
  url: "https://manager.example.com/query",
  fetchOptions: {
    headers: {
      Authorization: `Bearer ${process.env.PAT_TOKEN}`,
    },
  },
});

CLI Tools

bash
export PRODUCTIFY_TOKEN="pfy_abc123def456ghi789..."

# Use in commands
pfy projects list --token $PRODUCTIFY_TOKEN

Managing Tokens

Listing Your Tokens

Via UI: Navigate to SettingsPersonal Access Tokens to view all your tokens.

Via API:

graphql
query {
  myPersonalAccessTokens(
    filters: []
    order: { field: "created_at", direction: DESC }
    pagination: { limit: 20, offset: 0 }
  ) {
    id
    name
    tokenPrefix
    createdAt
    expiresAt
    revokedAt
    lastUsedAt
  }
}

Revoking a Token

Revoking a token immediately prevents it from being used for authentication.

Via UI:

  1. Navigate to SettingsPersonal Access Tokens
  2. Find the token to revoke
  3. Click Revoke
  4. Confirm the action

Via API:

graphql
mutation {
  revokePersonalAccessToken(id: "token-uuid") {
    id
    revokedAt
  }
}

TIP

Revoked tokens are not deleted but marked as revoked. This preserves audit history.

Deleting a Token

Deleting permanently removes the token record.

Via UI:

  1. Navigate to SettingsPersonal Access Tokens
  2. Find the token to delete
  3. Click Delete
  4. Confirm the action

Via API:

graphql
mutation {
  deletePersonalAccessToken(id: "token-uuid")
}

Token Expiration

Setting Expiration

When creating a token, you can optionally set an expiration date:

graphql
mutation {
  createPersonalAccessToken(
    name: "Temporary Token"
    expiresAt: "2025-12-31T23:59:59Z"
  ) {
    token
    personalAccessToken {
      expiresAt
    }
  }
}

No Expiration

Tokens without an expiration date remain valid indefinitely until revoked or deleted.

Use cases for non-expiring tokens:

  • Long-running services
  • Internal automation
  • Development environments

Use cases for expiring tokens:

  • Temporary access grants
  • External contractors
  • Security compliance requirements

Best Practices

Security

  • Store tokens securely - Use environment variables or secret managers
  • Never commit tokens to version control
  • Set expiration dates for tokens that don't need indefinite access
  • Revoke unused tokens - Clean up tokens that are no longer needed
  • Use descriptive names - Make it easy to identify token purpose
  • Rotate tokens regularly - Create new tokens and revoke old ones periodically

Organization

  • One token per use case - Create separate tokens for different tools/scripts
  • Name tokens clearly - Use names that indicate purpose and location (e.g., "Production CI/CD", "Development CLI")
  • Document token usage - Keep records of what each token is used for
  • Monitor token usage - Check lastUsedAt to identify unused tokens

Operational

  • Test tokens after creation - Verify tokens work before deploying to production
  • Have a rotation plan - Regularly create new tokens and retire old ones
  • Alert on expiration - Monitor tokens approaching expiration
  • Coordinate revocation - Plan token revocation to avoid service disruptions

Troubleshooting

Token Not Working

Check:

  • Token hasn't expired (expiresAt)
  • Token hasn't been revoked (revokedAt)
  • Token is correctly formatted in the Authorization header
  • Token includes the Bearer prefix in the header
  • Network connectivity to Manager API

Authentication Failures

Verify:

  • Authorization header format: Authorization: Bearer <token>
  • Token string is complete and unmodified
  • Token belongs to the user making the request
  • User account is active and not disabled

Token Not Found

Possible causes:

  • Token was deleted
  • Token belongs to different user
  • Token ID is incorrect
  • Database connectivity issues

Comparison with Machine Users

FeaturePersonal Access TokensMachine Users
ScopeUser-levelTenant-level
PurposePersonal automationService authentication
ExpirationOptionalNo expiration
AuthenticationBearer onlyBearer or Basic
Use CaseCLI tools, scriptsBackend services
Created ByIndividual usersAdministrators

When to use PATs:

  • Personal automation and scripts
  • CLI tool authentication
  • Development and testing
  • User-specific integrations

When to use Machine Users:

  • Production backend services
  • Service-to-service communication
  • Tenant-scoped operations
  • Long-running services

See Machine Users for service account authentication.

API Reference

Complete PAT management via GraphQL API:

graphql
# List tokens
query {
  myPersonalAccessTokens(
    filters: []
    order: { field: "created_at", direction: DESC }
    pagination: { limit: 20, offset: 0 }
  ) {
    id
    name
    tokenPrefix
    createdAt
    expiresAt
    lastUsedAt
  }
}

# Create token
mutation {
  createPersonalAccessToken(
    name: "New Token"
    expiresAt: "2025-12-31T23:59:59Z"
  ) {
    token
    personalAccessToken {
      id
      name
    }
  }
}

# Revoke token
mutation {
  revokePersonalAccessToken(id: "token-uuid") {
    id
    revokedAt
  }
}

# Delete token
mutation {
  deletePersonalAccessToken(id: "token-uuid")
}

See the full API Reference for details.