KeyHippo provides tools for managing the entire lifecycle of API keys, from creation to revocation.

Key Lifecycle Stages

  1. Creation: Generate new API keys for users or services.
  2. Distribution: Securely transmit keys to intended recipients.
  3. Usage: Authenticate and authorize requests using the keys.
  4. Monitoring: Track key usage, performance, and potential security issues.
  5. Rotation: Regularly update keys to maintain security.
  6. Revocation: Invalidate keys when they’re no longer needed or compromised.

Key Creation

KeyHippo offers both SQL and programmatic methods for key creation:

SQL Method:

SELECT keyhippo.create_api_key('user-uuid', 'Key Description') AS new_api_key;

Programmatic Method (TypeScript):

const keyHippo = new KeyHippo(supabaseClient);
const result = await keyHippo.createApiKey(userId, "Primary API Key");
console.log(result.apiKey); // The newly generated API key

Best Practices for Key Creation:

  • Generate keys with the principle of least privilege.
  • Use descriptive names for easy identification.
  • Implement rate limiting for key creation to prevent abuse.

Key Distribution

Securely distributing keys is crucial:

  1. Use encrypted channels (HTTPS) for transmission.
  2. Avoid sending keys via email or unsecured messaging platforms.
  3. Consider using a secure key vault or temporary viewing mechanism.

Example of a secure viewing mechanism:

function displayTemporaryKey(apiKey: string) {
  // Display key in UI
  setTimeout(() => {
    // Remove key from UI after a short period
  }, 30000); // 30 seconds
}

Key Usage and Authentication

KeyHippo seamlessly integrates with Supabase RLS for authentication:

CREATE POLICY "api_access"
ON public.resources
FOR SELECT
USING (
  auth.uid() = resources.owner_id
  OR auth.keyhippo_check(resources.owner_id)
);

Client-side usage:

const { data, error } = await supabase
  .from('resources')
  .select('*')
  .eq('id', resourceId)
  .single();

Monitoring and Analytics

KeyHippo provides functions to retrieve key metadata and usage statistics:

const metadata = await keyHippo.getAllKeyMetadata(userId);
metadata.forEach(keyData => {
  console.log(`Key ID: ${keyData.api_key_id}`);
  console.log(`Last Used: ${keyData.last_used}`);
  console.log(`Total Uses: ${keyData.total_uses}`);
  console.log(`Success Rate: ${keyData.success_rate}%`);
});

Best Practices for Monitoring:

  • Regularly review key usage patterns.
  • Set up alerts for unusual activity (e.g., sudden spike in usage).
  • Implement logging for all key operations.

Key Rotation

Regular key rotation is essential for maintaining security:

  1. Generate a new key.
  2. Update systems to use the new key.
  3. Set an expiration date for the old key.
  4. Revoke the old key after the grace period.

Example rotation process:

async function rotateApiKey(userId: string, oldKeyId: string) {
  const newKey = await keyHippo.createApiKey(userId, "Rotated Key");
  // Update systems to use newKey.apiKey
  // Set a reminder to revoke the old key
  setTimeout(async () => {
    await keyHippo.revokeApiKey(userId, oldKeyId);
  }, 7 * 24 * 60 * 60 * 1000); // 7 days
  return newKey;
}

Key Revocation

KeyHippo allows immediate revocation of keys:

await keyHippo.revokeApiKey(userId, apiKeyId);

Best Practices for Revocation:

  • Implement immediate revocation for compromised keys.
  • Set up automated revocation for unused or expired keys.
  • Maintain an audit log of all key revocations.

Handling Key Compromise

In case of a suspected key compromise:

  1. Immediately revoke the compromised key.
  2. Investigate the extent of the potential breach.
  3. Generate new keys for affected users/services.
  4. Review and update security measures.

Example compromise response:

async function handleKeyCompromise(userId: string, compromisedKeyId: string) {
  await keyHippo.revokeApiKey(userId, compromisedKeyId);
  // Log the incident
  console.log(`Key ${compromisedKeyId} compromised and revoked`);
  // Generate a new key
  const newKey = await keyHippo.createApiKey(userId, "Replacement for compromised key");
  // Notify user
  notifyUser(userId, "Security Alert: Your API key has been revoked due to potential compromise. A new key has been generated.");
  return newKey;
}

Best Practices for Lifecycle Management

  1. Automation: Automate as much of the lifecycle as possible to reduce human error.
  2. Least Privilege: Always issue keys with the minimum necessary permissions.
  3. Regular Audits: Conduct regular audits of active keys and their permissions.
  4. Education: Train developers and users on proper key management practices.
  5. Monitoring: Implement comprehensive monitoring and alerting systems.
  6. Documentation: Maintain clear documentation of all lifecycle processes.

Security Best Practices

Dive deeper into securing your API keys and overall application.