> For the complete documentation index, see [llms.txt](https://docs.gameket.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.gameket.io/introduction/authentication/security.md).

# Security

### API Key Rotation

If you suspect your API key has been compromised:

1. **Generate a new API key** in your merchant dashboard
2. **Update your application** to use the new key
3. **All old tokens become invalid immediately**

This provides instant revocation of all tokens associated with the compromised key.

#### 1. Store Credentials Securely

**❌ Don't:**

```javascript
const apiKey = "your_merchant_api_key"; // Exposed in code!
```

**✅ Do:**

```javascript
const apiKey = process.env.MERCHANT_API_KEY; // From .env file
```

#### 2. Never Log Tokens

**❌ Don't:**

```javascript
console.log("Token:", token); // Exposed in logs!
```

**✅ Do:**

```javascript
console.log("Token created at:", new Date()); // Only log metadata
```

#### 3. Use HTTPS Only

All API requests must be made over HTTPS. HTTP requests will be rejected.

#### 4. Rotate Keys Periodically

Even if not compromised, rotate your API keys every 90 days.

#### 5. Use Short-Lived Tokens

Tokens expire in 2 hours by design. Request new tokens frequently rather than storing old ones.

#### 6. Implement Token Caching

Avoid requesting new tokens on every request:

```javascript
class TokenManager {
  constructor() {
    this.token = null;
    this.expiresAt = null;
  }
  
  async getToken() {
    // Use cached token if still valid
    if (this.token && Date.now() < this.expiresAt - 60000) {
      return this.token;
    }
    
    // Request new token
    const response = await this.requestToken();
    this.token = response.token;
    this.expiresAt = new Date(response.expiresAt).getTime();
    
    return this.token;
  }
  
  async requestToken() {
    const response = await fetch('https://api.gameket.io/merchant/auth/check', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        apiKey: process.env.MERCHANT_API_KEY,
        secret: process.env.MERCHANT_SECRET
      })
    });
    
    if (!response.ok) throw new Error('Token request failed');
    const { data } = await response.json();
    return data;
  }
}
```

####
