User Guide/API Access

API Authentication

Secure your API access with authentication, permissions, and best practices

GoPie provides robust authentication mechanisms to secure your API access. This guide covers API key management, authentication methods, role-based access control, and security best practices.

Authentication Methods

GoPie supports multiple authentication methods for different use cases:

API Keys

The primary authentication method for server-to-server communication:

curl -H "Authorization: Bearer sk_live_abc123..." \
  https://api.gopie.app/v1/your-org/your-project/data

API keys start with prefixes indicating their type:

  • sk_live_ - Production secret keys
  • sk_test_ - Test environment keys
  • pk_live_ - Public keys (read-only)
  • rk_live_ - Restricted keys (custom permissions)

OAuth 2.0

For user-authorized applications:

Authorization Code Flow

Perfect for web applications:

// 1. Redirect to authorization
window.location = `https://auth.gopie.app/oauth/authorize?
  client_id=YOUR_CLIENT_ID&
  redirect_uri=https://yourapp.com/callback&
  response_type=code&
  scope=read:data write:data&
  state=random_string`;

// 2. Exchange code for token
const response = await fetch('https://auth.gopie.app/oauth/token', {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({
    grant_type: 'authorization_code',
    code: authorizationCode,
    client_id: YOUR_CLIENT_ID,
    client_secret: YOUR_CLIENT_SECRET,
    redirect_uri: 'https://yourapp.com/callback'
  })
});

Client Credentials Flow

For service-to-service authentication:

import requests

# Get access token
response = requests.post(
    'https://auth.gopie.app/oauth/token',
    data={
        'grant_type': 'client_credentials',
        'client_id': YOUR_CLIENT_ID,
        'client_secret': YOUR_CLIENT_SECRET,
        'scope': 'read:data write:data'
    }
)

access_token = response.json()['access_token']

# Use token for API calls
api_response = requests.get(
    'https://api.gopie.app/v1/org/project/data',
    headers={'Authorization': f'Bearer {access_token}'}
)

PKCE Flow

For mobile and single-page applications:

// 1. Generate code verifier and challenge
const codeVerifier = generateRandomString(128);
const codeChallenge = await sha256(codeVerifier);

// 2. Authorization request
window.location = `https://auth.gopie.app/oauth/authorize?
  client_id=YOUR_CLIENT_ID&
  redirect_uri=app://callback&
  response_type=code&
  scope=read:data&
  state=random_string&
  code_challenge=${codeChallenge}&
  code_challenge_method=S256`;

// 3. Token exchange with verifier
const tokenResponse = await fetch('https://auth.gopie.app/oauth/token', {
  method: 'POST',
  body: JSON.stringify({
    grant_type: 'authorization_code',
    code: authorizationCode,
    client_id: YOUR_CLIENT_ID,
    code_verifier: codeVerifier,
    redirect_uri: 'app://callback'
  })
});

JWT Tokens

For stateless authentication in microservices:

// Decode and verify JWT
const jwt = require('jsonwebtoken');

function verifyToken(token) {
  return jwt.verify(token, publicKey, {
    algorithms: ['RS256'],
    issuer: 'https://auth.gopie.app',
    audience: 'https://api.gopie.app'
  });
}

// Use in API request
const decoded = verifyToken(jwtToken);
const response = await fetch(`https://api.gopie.app/v1/${decoded.org}/data`, {
  headers: {'Authorization': `Bearer ${jwtToken}`}
});

API Key Management

Creating API Keys

Go to Settings → API Keys in your GoPie dashboard

Create New Key

Click "Create API Key" and configure:

  • Name: Descriptive identifier
  • Permissions: Read, write, or custom
  • Datasets: Specific access or all
  • Expiration: Optional expiry date

Save Securely

Copy the key immediately - it won't be shown again

Key Types and Permissions

Key TypePermissionsUse Case
Secret KeyFull accessServer-side applications
Public KeyRead-onlyClient-side queries
Restricted KeyCustom permissionsLimited access scenarios
Temporary KeyTime-limitedShort-term access

Key Rotation

Implement regular key rotation:

// Automated key rotation example
async function rotateApiKey(oldKey) {
  // Create new key
  const newKey = await gopieAdmin.createApiKey({
    name: 'Rotated Key',
    permissions: ['read:data', 'write:data'],
    expiresIn: '90d'
  });
  
  // Update application configuration
  await updateConfig({
    GOPIE_API_KEY: newKey.secret
  });
  
  // Schedule old key deletion
  setTimeout(async () => {
    await gopieAdmin.revokeApiKey(oldKey);
  }, 24 * 60 * 60 * 1000); // 24 hours
  
  return newKey;
}

Security Best Practices

Secure Key Storage

Never commit API keys to version control!

Use environment variables or secret management services.

Using Environment Variables

# .env file (add to .gitignore)
GOPIE_API_KEY=sk_live_abc123...
// Node.js
require('dotenv').config();
const apiKey = process.env.GOPIE_API_KEY;

// Python
import os
api_key = os.environ.get('GOPIE_API_KEY')

AWS Secrets Manager

const AWS = require('aws-sdk');
const secretsManager = new AWS.SecretsManager();

async function getApiKey() {
  const secret = await secretsManager.getSecretValue({
    SecretId: 'gopie-api-key'
  }).promise();
  
  return JSON.parse(secret.SecretString).apiKey;
}

HashiCorp Vault

import hvac

client = hvac.Client(url='https://vault.company.com')
client.token = vault_token

# Read secret
response = client.secrets.kv.v2.read_secret_version(
    path='gopie/api-key'
)
api_key = response['data']['data']['key']

Network Security

IP Whitelisting

Restrict API key usage to specific IPs:

{
  "key_settings": {
    "allowed_ips": [
      "203.0.113.0/24",
      "198.51.100.14"
    ],
    "deny_all_others": true
  }
}

HTTPS Only

Always use HTTPS for API calls:

// Good
fetch('https://api.gopie.app/v1/data', {
  headers: {'Authorization': `Bearer ${apiKey}`}
});

// Never use HTTP
fetch('http://api.gopie.app/v1/data', {
  headers: {'Authorization': `Bearer ${apiKey}`}
});

Token Security

Short-Lived Tokens

Use short expiration times for enhanced security:

// Request token with custom expiration
const token = await gopieAuth.createToken({
  expiresIn: '1h', // 1 hour
  scopes: ['read:data'],
  datasets: ['sales-2024']
});

// Refresh before expiration
setInterval(async () => {
  const newToken = await gopieAuth.refreshToken(token);
  updateAuthHeader(newToken);
}, 50 * 60 * 1000); // Refresh every 50 minutes

Token Scoping

Limit token permissions to minimum required:

{
  "scopes": [
    "read:datasets.sales",
    "read:datasets.inventory",
    "execute:queries"
  ],
  "denied_operations": [
    "delete:*",
    "write:sensitive_data"
  ]
}

Role-Based Access Control

Permission Levels

GoPie uses a hierarchical permission system:

organization:
  admin:
    - manage:organization
    - manage:billing
    - manage:users
    - all:projects
  
  project:
    owner:
      - manage:project
      - manage:datasets
      - manage:api_keys
      - execute:queries
    
    editor:
      - create:datasets
      - update:datasets
      - execute:queries
      - read:api_keys
    
    viewer:
      - read:datasets
      - execute:queries.readonly

Custom Roles

Create custom roles for specific needs:

const customRole = await gopieAdmin.createRole({
  name: 'data-analyst',
  permissions: [
    'read:all_datasets',
    'execute:queries',
    'create:charts',
    'export:data'
  ],
  restrictions: {
    datasets: ['sales', 'marketing'],
    query_timeout: 300, // 5 minutes
    export_limit: 10000 // rows
  }
});

API Key Permissions

Assign specific permissions to API keys:

# Create key with limited permissions
gopie keys create \
  --name "Analytics Dashboard" \
  --permissions read:datasets,execute:queries \
  --datasets sales,customers \
  --rate-limit 1000/hour

Authentication Flows

Server-Side Applications

Store API Key Securely

Use environment variables or secret management

Initialize Client

const GoPie = require('@gopie/sdk');
const client = new GoPie({
  apiKey: process.env.GOPIE_API_KEY
});

Make Authenticated Requests

const data = await client.datasets.query({
  dataset: 'sales',
  sql: 'SELECT * FROM orders WHERE date >= ?',
  params: ['2024-01-01']
});

Client-Side Applications

Request Temporary Token

Your backend requests a limited token

// Backend endpoint
app.post('/api/gopie-token', async (req, res) => {
  const token = await gopie.createPublicToken({
    datasets: ['public_data'],
    expiresIn: '1h',
    operations: ['read']
  });
  res.json({ token });
});

Use Token in Frontend

// Frontend
const { token } = await fetch('/api/gopie-token').then(r => r.json());

const response = await fetch('https://api.gopie.app/v1/data', {
  headers: {'Authorization': `Bearer ${token}`}
});

Handle Token Expiration

if (response.status === 401) {
  // Token expired, request new one
  await refreshToken();
}

Monitoring and Auditing

API Key Usage

Monitor key usage in the dashboard:

  • Request count by key
  • Geographic distribution
  • Error rates
  • Suspicious activity alerts

Audit Logs

Access detailed audit logs:

{
  "timestamp": "2024-01-15T10:30:00Z",
  "api_key_id": "key_abc123",
  "operation": "query.execute",
  "dataset": "sales",
  "ip_address": "203.0.113.1",
  "user_agent": "MyApp/1.0",
  "response_code": 200,
  "response_time_ms": 145
}

Security Alerts

Configure alerts for:

  • Failed authentication attempts
  • Unusual access patterns
  • Rate limit violations
  • Expired key usage
  • Geographic anomalies

Troubleshooting

Common Issues

Invalid API Key

{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The provided API key is invalid or has been revoked"
  }
}

Solution: Verify key in dashboard, check for typos

Insufficient Permissions

{
  "error": {
    "code": "INSUFFICIENT_PERMISSIONS",
    "message": "This API key doesn't have permission to access this dataset"
  }
}

Solution: Update key permissions or use appropriate key

Rate Limit Exceeded

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded. Retry after 3600 seconds"
  }
}

Solution: Implement backoff, upgrade plan, or optimize requests

Debug Mode

Enable debug mode for detailed auth information:

const client = new GoPie({
  apiKey: process.env.GOPIE_API_KEY,
  debug: true // Logs auth headers and responses
});

What's Next?