API Client Registration

Learn how to register and manage API clients in the Exepron Identity Server. This guide covers client types, configuration options, and best practices for securing your integration.

📝 Note: This documentation uses placeholder URLs. Replace {YOUR_IDENTITY_SERVER} with your Identity Server URL (e.g., identity.yourdomain.com or localhost:44367 for local development) and {YOUR_API_SERVER} with your API Server URL (e.g., api.yourdomain.com or localhost:44395 for local development).
Manage Your API Clients: To create and manage API clients, access the API Client Management page at https://{YOUR_IDENTITY_SERVER}/Identity/Account/Manage/ApiClients in your profile settings.

What are API Clients?

API clients are applications that interact with the Exepron REST API on behalf of users or systems. Each client must be registered in the Exepron Identity Server to obtain credentials for authentication.

Key Concepts

Client ID

A unique public identifier for your application. This is safe to expose in client-side code.

Client Secret

A private key used to authenticate confidential clients. Must be kept secure and never exposed in client-side code.

Grant Types

OAuth 2.0 flows that the client is allowed to use (e.g., authorization_code, password).

Scopes

Permissions that define what resources the client can access.

When You Need an API Client

  • Building a web application that integrates with Exepron
  • Creating a mobile app for project management
  • Developing automated scripts or services
  • Integrating Exepron with other business systems
  • Building custom dashboards or reporting tools

Client Types

Exepron provides three simplified templates for creating API clients. Choose the template that best matches your use case:

Account Limit: Each account can have up to 10 active API clients.

Personal Access Token (PAT)

Best for: Quick testing, personal scripts, and CLI tools

Use Cases:

  • Testing API endpoints in Postman or curl
  • Personal automation scripts
  • One-off data imports/exports
  • Development and debugging

Configuration:

  • Grant Type: Password (Resource Owner)
  • Secret Required: Yes (included in token)
  • Token Expiration: 30 days, 90 days, 1 year, or never
  • Scopes: exepron.restapi, exepron.restapi:extended
Security Note: Personal Access Tokens are sensitive credentials. Treat them like passwords and never commit them to version control.

Token Format:

exepron_pat_[client-id]:[secret]

Example:
exepron_pat_abc123def456:dGVzdHNlY3JldA==

Backend Service

Best for: Server-to-server integrations and automated services

Use Cases:

  • Scheduled jobs and background workers
  • Integration services (ETL, data sync)
  • Microservices communicating with Exepron
  • Server-side automation

Configuration:

  • Grant Type: Password (Resource Owner)
  • Secret Required: Yes
  • Token Lifetime: 1 hour
  • Scopes: openid, profile, exepron.restapi
Best Practice: Store client credentials in environment variables or secure secret management services (Azure Key Vault, AWS Secrets Manager, etc.).

Web/Mobile App

Best for: User-facing applications that require user authentication

Use Cases:

  • Single-page applications (React, Angular, Vue)
  • Mobile applications (iOS, Android, React Native)
  • Progressive Web Apps (PWAs)
  • Desktop applications with web views

Configuration:

  • Grant Type: Authorization Code with PKCE
  • Secret Required: No (public client)
  • PKCE: Required (SHA256 only)
  • Token Lifetime: 1 hour (access), 30 days (refresh)
  • Scopes: openid, profile, email, exepron.restapi, offline_access
  • Redirect URIs: Required (must be pre-registered)
Security Features: PKCE protection, refresh token rotation, and strict redirect URI validation ensure maximum security for public clients.

Comparison Table

Feature Personal Access Token Backend Service Web/Mobile App
Grant Type Password Password Authorization Code + PKCE
Requires Secret Yes (embedded in token) Yes No
User Context Yes (creator's identity) No Yes (authenticated user)
Refresh Tokens No No Yes
Redirect URIs Not required Not required Required
Best Use Case Quick testing, scripts Server-to-server User-facing apps

Step-by-Step Registration Guide

Follow these steps to create API clients in the Exepron Identity Server:

1

Access API Client Management

Navigate to the Exepron Identity Server and log in:

https://{YOUR_IDENTITY_SERVER}

Then access the API Client Management page via your profile settings.

API Client Management Page
2

Choose Client Template

Select one of the three available templates based on your use case:

  • Personal Access Token: For testing and scripts
  • Backend Service: For server-to-server integration
  • Web/Mobile App: For user-facing applications
Three Client Type Templates

Creating a Personal Access Token

1

Fill in Token Details

Provide the following information:

  • Token Name: A descriptive name (e.g., "Local Development Testing")
  • Token Expiration: Choose from 30 days, 90 days, 1 year, or never
Personal Access Token Creation Form
2

Copy Your Token

After creation, copy your token immediately - it won't be shown again:

exepron_pat_abc123def456:dGVzdHNlY3JldA==

⚠️ Store this token securely!
It won't be shown again.

Usage: Use this token as a Bearer token in the Authorization header:

curl -H "Authorization: Bearer exepron_pat_abc123def456:dGVzdHNlY3JldA==" \
  https://{YOUR_API_SERVER}/odata/Projects

Creating a Backend Service

1

Fill in Service Details

Provide the following information:

  • Service Name: A descriptive name (e.g., "Data Sync Service")
  • Description: Optional description of the service's purpose
2

Copy Credentials

Save your client credentials immediately:

Client ID: service_abc123def456
Client Secret: dGVzdHNlY3JldA==

⚠️ Store these credentials securely!
The secret won't be shown again.

Usage: Exchange credentials for an access token:

POST https://{YOUR_IDENTITY_SERVER}/connect/token
Content-Type: application/x-www-form-urlencoded

grant_type=password
&username=USER_EMAIL
&password=USER_PASSWORD
&client_id=service_abc123def456
&client_secret=dGVzdHNlY3JldA==
&scope=exepron.restapi

Creating a Web/Mobile App

1

Fill in App Details

Provide the following information:

  • App Name: A descriptive name (e.g., "React Dashboard")
  • Redirect URLs: One per line (HTTPS required for production)
    https://app.example.com/callback
    http://localhost:3000/callback
  • Description: Optional description
Important: Only HTTPS URLs are allowed for non-localhost domains. HTTP is only permitted for localhost/127.0.0.1.
2

Copy Client ID

No client secret is needed (public client). Copy your client ID:

Client ID: app_abc123def456
Grant Type: Authorization Code + PKCE
Redirect URIs:
- https://app.example.com/callback
- http://localhost:3000/callback

Usage: Implement Authorization Code flow with PKCE in your application. See the Authentication Guide for detailed implementation examples.

Client Configuration Options

Essential Settings

Setting Description Default Recommended
Access Token Lifetime How long access tokens are valid 3600s (1 hour) 3600s
Refresh Token Lifetime How long refresh tokens are valid 2592000s (30 days) 2592000s
Require PKCE Enforce PKCE for authorization code flow False True (always)
Allow Offline Access Enable refresh tokens False True
Sliding Refresh Token Refresh token renews on use False True
Update Access Token on Refresh Update claims on token refresh False True

Configuration Examples

Single Page Application (SPA)

{
  "clientId": "spa-client",
  "clientName": "React Dashboard",
  "clientType": "public",
  "grantTypes": ["authorization_code"],
  "redirectUris": [
    "https://app.example.com/callback",
    "http://localhost:3000/callback"
  ],
  "postLogoutRedirectUris": [
    "https://app.example.com",
    "http://localhost:3000"
  ],
  "allowedCorsOrigins": [
    "https://app.example.com",
    "http://localhost:3000"
  ],
  "requirePkce": true,
  "allowOfflineAccess": true,
  "scopes": ["openid", "profile", "api1", "offline_access"]
}

Mobile Application

{
  "clientId": "mobile-app",
  "clientName": "Exepron Mobile",
  "clientType": "public",
  "grantTypes": ["authorization_code"],
  "redirectUris": [
    "com.exepron.mobile://callback",
    "exepron://oauth/redirect"
  ],
  "requirePkce": true,
  "allowOfflineAccess": true,
  "refreshTokenLifetime": 7776000,  // 90 days for mobile
  "scopes": ["openid", "profile", "api1", "offline_access"]
}

Backend Service

{
  "clientId": "backend-service",
  "clientName": "Data Sync Service",
  "clientType": "confidential",
  "grantTypes": ["password"],
  "clientSecrets": [
    {
      "value": "supersecret123",
      "expiration": "2026-01-01"
    }
  ],
  "scopes": ["api1"],
  "claims": [
    {
      "type": "service",
      "value": "data-sync"
    }
  ]
}

Redirect URI Configuration

URI Requirements

  • Must be absolute URIs (not relative paths)
  • HTTPS required for production (HTTP allowed only for localhost)
  • Exact match required (no wildcards in production)
  • Case-sensitive matching
  • Query strings and fragments not allowed

Common Redirect URI Patterns

Web Applications

# Production
https://app.example.com/auth/callback
https://app.example.com/silent-renew

# Staging
https://staging.example.com/auth/callback

# Development
http://localhost:3000/auth/callback
http://localhost:4200/auth/callback
http://127.0.0.1:8080/callback

Mobile Applications

# iOS (Custom Scheme)
com.example.app://oauth/callback
com.example.app://auth/redirect

# iOS (Universal Links)
https://app.example.com/ios/oauth/callback

# Android (Custom Scheme)
com.example.app://oauth/redirect

# Android (App Links)
https://app.example.com/android/oauth/callback

Desktop Applications

# Loopback for native apps
http://localhost/callback
http://127.0.0.1:PORT/callback

# Custom protocol
myapp://auth/callback

Silent Token Renewal

For SPAs, configure a separate URI for silent token renewal:

// Main callback
https://app.example.com/callback

// Silent renewal frame
https://app.example.com/silent-renew.html
Tip: The silent renewal page should be a minimal HTML page that only handles token renewal without loading your full application.

Scopes Assignment

Understanding Scopes

Scopes define what resources and operations your client can access. Follow the principle of least privilege - only request scopes you actually need.

Available Scopes

Identity Scopes (OIDC)

Scope Description Claims Included
openid OpenID Connect protocol sub (user ID)
profile User profile information name, given_name, family_name, preferred_username
email Email address email, email_verified
address Physical address address
phone Phone number phone_number, phone_number_verified

API Access Scopes

Scope Description Access Level
api1 Full API access Read/Write all resources
api1.read Read-only API access Read all resources
projects Project management CRUD on projects
projects.read View projects Read projects only
tasks Task management CRUD on tasks
tasks.read View tasks Read tasks only
resources Resource management Manage team/equipment
reports Reporting access Generate/view reports
webhooks Webhook management Configure webhooks
admin Administrative access All operations

Special Scopes

Scope Description Use Case
offline_access Refresh tokens Long-lived access without re-auth
role User roles Include roles in token

Scope Combinations

Common scope combinations for different use cases:

# Read-only dashboard
scopes: ["openid", "profile", "api1.read"]

# Full-featured web app
scopes: ["openid", "profile", "email", "api1", "offline_access"]

# Backend service
scopes: ["api1"]

# Mobile app with offline support
scopes: ["openid", "profile", "api1", "offline_access"]

# Reporting tool
scopes: ["projects.read", "tasks.read", "reports"]

Client Secrets Management

Generating Secrets

Client secrets are automatically generated when creating confidential clients. You can also generate new secrets manually:

# Generate a secure secret (example)
openssl rand -hex 32
# Output: 7f3d8c2a9b5e4f1d8a6c3e2f9d5b7a1c4e8f2a5d7b9c3e6f8a2d5e8b1c4f7a9d

Secret Rotation

Regularly rotate client secrets for security:

1

Generate New Secret

Add a new secret without removing the old one

2

Update Applications

Deploy your application with the new secret

3

Monitor Usage

Ensure all instances are using the new secret

4

Remove Old Secret

Delete the old secret after verification

Storing Secrets Securely

DO:

  • ✅ Use environment variables
  • ✅ Use secret management services (Azure Key Vault, AWS Secrets Manager)
  • ✅ Encrypt secrets at rest
  • ✅ Use different secrets per environment
  • ✅ Rotate secrets regularly

DON'T:

  • ❌ Commit secrets to version control
  • ❌ Include secrets in client-side code
  • ❌ Share secrets via email or chat
  • ❌ Use the same secret across environments
  • ❌ Log or display secrets in plain text

Environment Variable Example

# .env file (add to .gitignore!)
EXEPRON_CLIENT_ID=web-dashboard-prod
EXEPRON_CLIENT_SECRET=7f3d8c2a9b5e4f1d8a6c3e2f9d5b7a1c

# Node.js usage
const clientId = process.env.EXEPRON_CLIENT_ID;
const clientSecret = process.env.EXEPRON_CLIENT_SECRET;

# .NET usage
var clientId = Configuration["Exepron:ClientId"];
var clientSecret = Configuration["Exepron:ClientSecret"];

# Python usage
import os
client_id = os.environ.get('EXEPRON_CLIENT_ID')
client_secret = os.environ.get('EXEPRON_CLIENT_SECRET')

Managing Existing Clients

Viewing Your API Clients

Access the API Client Management page to view all your clients:

  • Client Name and ID
  • Client Type (Personal Token, Backend Service, Web/Mobile App)
  • Grant Types and Scopes
  • Creation date and last accessed date
  • Active/Inactive status

Editing Clients

You can update certain properties of existing API clients. The editable fields depend on the client type:

Web/Mobile App Clients:

  • Display Name: Update the application name (3-200 characters)
  • Description: Update or add an optional description
  • Redirect URIs: Modify callback URLs for authentication (one per line)
Auto-Generated Settings: When you update Redirect URIs, the following are automatically regenerated:
  • Post-Logout Redirect URIs (same as Redirect URIs)
  • Allowed CORS Origins (extracted from Redirect URI origins)

Backend Service Clients:

  • Display Name: Update the service name
  • Description: Update or add an optional description

Personal Access Tokens:

  • Display Name: Update the token name

To edit a client:

  1. Navigate to the API Client Management page
  2. Find the client you want to edit
  3. Click the Edit button (pencil icon)
  4. Modify the desired fields in the edit modal
  5. Click "Save Changes"
Note: Client ID and Grant Types cannot be changed after creation. If you need different settings, create a new client.

Regenerating Client Secrets

If you need to rotate or regenerate a client secret:

  1. Navigate to the API Client Management page
  2. Find the client you want to update
  3. Click the "Regenerate Secret" button
  4. Copy the new secret immediately (it won't be shown again)
  5. Update your application with the new secret
Important: The old secret is invalidated immediately. Ensure you update all instances of your application before regenerating.

Secret Rotation Best Practices:

  • Rotate secrets regularly (every 90-180 days)
  • Set calendar reminders for secret expiration dates
  • Test with new secret before revoking old one (if possible)
  • Keep a secure backup of active secrets
  • Document which services use which clients

Deactivating Clients

Temporarily disable a client without deletion:

  1. Navigate to the API Client Management page
  2. Find the client you want to deactivate
  3. Click the "Deactivate" button
  4. Deactivated clients cannot authenticate until reactivated
Note: Deactivation is immediate. All active tokens for the client will be invalidated.

Client Limit

Each account is limited to 10 active API clients. To create new clients after reaching the limit:

  • Deactivate unused clients
  • Delete clients that are no longer needed
  • Consolidate multiple clients if possible

Monitoring Client Usage

Track when your clients were last used:

  • Created On: When the client was first created
  • Last Used On: When the client last successfully authenticated

Use this information to identify unused clients that can be safely deactivated or deleted.

Best Practices

1. Use Separate Clients per Environment

Create distinct clients for development, staging, and production:

myapp-dev     → Development
myapp-staging → Staging
myapp-prod    → Production

2. Follow Naming Conventions

Use consistent, descriptive names:

Format: [app]-[platform]-[environment]
Examples:
- dashboard-web-prod
- mobile-ios-staging
- sync-service-dev

3. Implement Least Privilege

Only request the minimum scopes needed:

# Too broad
scopes: ["api1", "admin"]

# Better
scopes: ["projects.read", "tasks.read"]

4. Regular Audits

  • Review client list quarterly
  • Remove unused clients
  • Verify scope assignments
  • Check for suspicious activity
  • Update redirect URIs

5. Document Your Clients

Maintain documentation for each client:

  • Purpose and owner
  • Deployment locations
  • Contact information
  • Dependencies
  • Rotation schedule

6. Monitor and Alert

Set up monitoring for:

  • Failed authentication attempts
  • Unusual traffic patterns
  • Expired secrets
  • Deprecated grant types

Troubleshooting

Client Not Found

Error: invalid_client

Causes:

  • Incorrect Client ID
  • Client has been deleted
  • Client is disabled

Solution:

  • Verify Client ID matches exactly
  • Check if client is enabled
  • Confirm client exists in Identity Server

Invalid Redirect URI

Error: invalid_redirect_uri

Causes:

  • URI not registered
  • Case mismatch
  • Protocol mismatch (http vs https)

Solution:

  • Add exact URI to client configuration
  • Check for trailing slashes
  • Ensure protocol matches

Scope Not Allowed

Error: invalid_scope

Causes:

  • Scope not assigned to client
  • Scope doesn't exist
  • Typo in scope name

Solution:

  • Add scope to client configuration
  • Verify scope name is correct
  • Check scope exists in Identity Server

Grant Type Not Allowed

Error: unsupported_grant_type

Causes:

  • Grant type not configured
  • Wrong grant type for client type

Solution:

  • Enable required grant type
  • Use appropriate grant for client type
  • Public clients can't use password flow (requires client secret)

Additional Resources