Skip to main content

Service Credentials

Securely retrieve credentials for external service integrations.


Get Service Credentials

Retrieves the authentication credentials for a specific external service.

Endpoint: GET /api/v1/services/{id}/credentials

Request

curl -X GET "https://dev.api.authsec.dev/exsvc/api/v1/services/svc_abc123/credentials" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json"

Path Parameters

ParameterTypeDescription
idstringService ID

Response

Status: 200 OK

{
"service_id": "svc_abc123",
"credentials": {
"api_key": "sk_live_51A...xyz",
"api_secret": "whsec_...abc",
"client_id": "ca_...123",
"environment": "production"
},
"metadata": {
"last_rotated": "2026-02-01T00:00:00Z",
"expires_at": "2027-02-01T00:00:00Z"
},
"created_at": "2026-02-10T10:30:00Z",
"updated_at": "2026-02-11T14:00:00Z"
}

Error Responses

404 Not Found - Service doesn't exist:

{
"error": {
"code": "SERVICE_NOT_FOUND",
"message": "Service with ID 'svc_abc123' not found"
}
}

404 Not Found - Credentials not configured:

{
"error": {
"code": "CREDENTIALS_NOT_FOUND",
"message": "No credentials found for service 'svc_abc123'"
}
}

403 Forbidden - Insufficient permissions:

{
"error": {
"code": "INSUFFICIENT_PERMISSIONS",
"message": "User does not have permission to view credentials"
}
}

Credential Object Structure

The credentials object structure varies by service type, but commonly includes:

FieldTypeDescription
service_idstringAssociated service ID
credentialsobjectCredential data (varies by service)
metadataobjectAdditional metadata
created_attimestampCredential creation timestamp
updated_attimestampLast update timestamp

Common Credential Fields

FieldTypeUse Case
api_keystringAPI authentication key
api_secretstringSecret key for signing requests
client_idstringOAuth client identifier
client_secretstringOAuth client secret
access_tokenstringAccess token for API calls
refresh_tokenstringToken for refreshing access
webhook_secretstringSecret for validating webhooks
environmentstringEnvironment identifier (production, staging)

Security Considerations

Best Practices

1. Secure Storage

  • Never log credentials in application logs
  • Encrypt credentials at rest in your application
  • Use environment variables for credential storage
  • Avoid hardcoding credentials in source code

2. Access Control

  • Implement RBAC for credential access
  • Audit credential retrieval for security monitoring
  • Use time-limited tokens when possible
  • Rotate credentials regularly

3. Transmission Security

  • Always use HTTPS for API calls
  • Validate SSL certificates on connections
  • Use TLS 1.2 or higher for all communications

4. Application Security

# ❌ BAD: Logging credentials
logger.info(f"API Key: {credentials['api_key']}")

# ✅ GOOD: Masking sensitive data
logger.info("API Key retrieved successfully")

# ❌ BAD: Storing in plaintext
with open('config.txt', 'w') as f:
f.write(credentials['api_key'])

# ✅ GOOD: Using environment variables
import os
os.environ['STRIPE_API_KEY'] = credentials['api_key']

Code Examples

Python

import requests
import os

BASE_URL = "https://dev.api.authsec.dev/exsvc"
TOKEN = "your_jwt_token"

headers = {
"Authorization": f"Bearer {TOKEN}",
"Content-Type": "application/json"
}

def get_service_credentials(service_id: str):
"""
Securely retrieve service credentials
"""
try:
response = requests.get(
f"{BASE_URL}/api/v1/services/{service_id}/credentials",
headers=headers
)
response.raise_for_status()

data = response.json()
credentials = data['credentials']

# Store in environment variables (never log!)
for key, value in credentials.items():
env_key = f"SERVICE_{service_id.upper()}_{key.upper()}"
os.environ[env_key] = str(value)

return credentials

except requests.exceptions.HTTPError as e:
if e.response.status_code == 404:
print(f"Service or credentials not found: {service_id}")
elif e.response.status_code == 403:
print(f"Insufficient permissions to access credentials")
else:
print(f"Error retrieving credentials: {e}")
return None

# Usage
service_id = "svc_abc123"
credentials = get_service_credentials(service_id)

if credentials:
# Use credentials (retrieved from environment)
api_key = os.environ.get(f"SERVICE_{service_id.upper()}_API_KEY")
# Make external API call with credentials

TypeScript

interface ServiceCredentials {
service_id: string;
credentials: Record<string, string>;
metadata: {
last_rotated?: string;
expires_at?: string;
};
created_at: string;
updated_at: string;
}

const BASE_URL = "https://dev.api.authsec.dev/exsvc";
const TOKEN = "your_jwt_token";

async function getServiceCredentials(
serviceId: string
): Promise<ServiceCredentials | null> {
try {
const response = await fetch(
`${BASE_URL}/api/v1/services/${serviceId}/credentials`,
{
headers: {
"Authorization": `Bearer ${TOKEN}`,
"Content-Type": "application/json"
}
}
);

if (!response.ok) {
if (response.status === 404) {
console.error(`Service or credentials not found: ${serviceId}`);
} else if (response.status === 403) {
console.error("Insufficient permissions to access credentials");
} else {
console.error(`Error: ${response.statusText}`);
}
return null;
}

const data: ServiceCredentials = await response.json();

// Store credentials securely (e.g., in-memory cache, not localStorage)
// Never log credentials
console.log("Credentials retrieved successfully");

return data;

} catch (error) {
console.error("Failed to retrieve credentials:", error);
return null;
}
}

// Usage
async function useServiceCredentials() {
const serviceId = "svc_abc123";
const credData = await getServiceCredentials(serviceId);

if (credData) {
const { api_key, api_secret } = credData.credentials;

// Use credentials for external service calls
// Make sure to handle them securely
}
}

Credential Rotation

When to Rotate

  • Scheduled: Every 90 days as a best practice
  • Compromised: Immediately if credentials are exposed
  • Employee Offboarding: When team members leave
  • Security Audit: After security reviews recommend rotation

Rotation Workflow

  1. Generate New Credentials in the external service
  2. Update Credentials in External Service API (via service update)
  3. Deploy Updated Configuration to your applications
  4. Verify Functionality with new credentials
  5. Revoke Old Credentials in the external service

Monitoring Expiration

from datetime import datetime, timedelta

def check_credential_expiration(service_id: str):
"""
Check if credentials are expiring soon
"""
cred_data = get_service_credentials(service_id)

if not cred_data or 'metadata' not in cred_data:
return

expires_at_str = cred_data['metadata'].get('expires_at')
if not expires_at_str:
return

expires_at = datetime.fromisoformat(expires_at_str.replace('Z', '+00:00'))
days_until_expiry = (expires_at - datetime.now()).days

if days_until_expiry < 30:
print(f"⚠️ Credentials expire in {days_until_expiry} days!")
print("Consider rotating credentials soon")
elif days_until_expiry < 7:
print(f"🚨 URGENT: Credentials expire in {days_until_expiry} days!")
print("Rotate credentials immediately")

Common Use Cases

1. Payment Gateway Integration

# Retrieve Stripe credentials
stripe_creds = get_service_credentials("stripe_production")
stripe.api_key = stripe_creds['credentials']['api_key']

# Create a payment
payment = stripe.PaymentIntent.create(
amount=2000,
currency="usd",
payment_method_types=["card"]
)

2. Email Service Integration

# Retrieve SendGrid credentials
sendgrid_creds = get_service_credentials("sendgrid_production")
api_key = sendgrid_creds['credentials']['api_key']

# Send email
import sendgrid
from sendgrid.helpers.mail import Mail

sg = sendgrid.SendGridAPIClient(api_key)
message = Mail(
from_email='[email protected]',
to_emails='[email protected]',
subject='Hello',
html_content='<strong>Message</strong>'
)
response = sg.send(message)

3. Cloud Storage Integration

# Retrieve AWS S3 credentials
s3_creds = get_service_credentials("aws_s3_production")
creds = s3_creds['credentials']

import boto3

s3_client = boto3.client(
's3',
aws_access_key_id=creds['access_key_id'],
aws_secret_access_key=creds['secret_access_key']
)

# Upload file
s3_client.upload_file('local_file.txt', 'bucket-name', 'file.txt')

Troubleshooting

Credentials Not Found

Problem: 404 CREDENTIALS_NOT_FOUND error

Solutions:

  1. Verify service exists: GET /api/v1/services/{id}
  2. Check if credentials were set for the service
  3. Confirm you have the correct service ID

Insufficient Permissions

Problem: 403 INSUFFICIENT_PERMISSIONS error

Solutions:

  1. Verify your JWT token has required scopes
  2. Check RBAC permissions for credential access
  3. Contact your administrator for elevated access

Expired Credentials

Problem: External service returns authentication errors

Solutions:

  1. Check credential expiration date in metadata
  2. Rotate credentials if expired
  3. Implement automatic expiration monitoring

Next Steps