# Credential Security

### **Core Concepts**

#### **Environment Variables**

Cyne AI uses a hierarchical system for environment variables:

1. **Character-specific secrets** (highest priority).
2. **Environment variables** defined in `.env` files.
3. **Default values** (lowest priority).

***

#### **Secret Types**

Common secrets managed in Cyne AI:

```env
# API Keys
OPENAI_API_KEY=sk-your-openai-key

# Client Authentication
DISCORD_API_TOKEN=your-discord-token
TELEGRAM_BOT_TOKEN=your-telegram-token

# Solana Wallet Credentials
SOLANA_PRIVATE_KEY=example-private-key
SOLANA_PUBLIC_KEY=example-public-key
```

***

### **Implementation Guide**

#### **Basic Setup**

1. Create a `.env` file from the provided template:

   ```bash
   cp .env.example .env
   ```
2. Configure environment variable discovery in your code:

   ```typescript
   import { config } from "dotenv";
   config(); // Load environment variables
   ```

***

#### **Character-Specific Secrets**

Define secrets directly in character files for modular configuration:

```json
{
  "name": "TradingAgent",
  "settings": {
    "secrets": {
      "OPENAI_API_KEY": "character-specific-key",
      "SOLANA_PRIVATE_KEY": "character-specific-wallet"
    }
  }
}
```

Access secrets in your code:

```typescript
const apiKey = runtime.getSetting("OPENAI_API_KEY");
```

***

### **Secure Storage**

#### **Wallet Management**

Handle Solana wallet credentials securely:

```typescript
class WalletManager {
  private async initializeWallet(runtime: IAgentRuntime) {
    const privateKey = runtime.getSetting("SOLANA_PRIVATE_KEY");
    if (!privateKey) {
      throw new Error("Wallet private key not configured");
    }
    // Validate and initialize the wallet
    const keyBuffer = Buffer.from(privateKey, "base64");
    if (keyBuffer.length !== 64) {
      throw new Error("Invalid key format");
    }
    return new Wallet(privateKey);
  }
}
```

***

#### **Encryption for Secrets**

Encrypt sensitive secrets before storage:

```typescript
import { createCipheriv, createDecipheriv, randomBytes } from "crypto";

class SecretEncryption {
  static async encrypt(value: string, key: Buffer): Promise<string> {
    const iv = randomBytes(16);
    const cipher = createCipheriv("aes-256-gcm", key, iv);
    let encrypted = cipher.update(value, "utf8", "hex");
    encrypted += cipher.final("hex");
    return JSON.stringify({
      iv: iv.toString("hex"),
      encrypted,
      tag: cipher.getAuthTag().toString("hex")
    });
  }

  static async decrypt(encrypted: string, key: Buffer): Promise<string> {
    const { iv, encrypted: encryptedData, tag } = JSON.parse(encrypted);
    const decipher = createDecipheriv("aes-256-gcm", key, Buffer.from(iv, "hex"));
    decipher.setAuthTag(Buffer.from(tag, "hex"));
    let decrypted = decipher.update(encryptedData, "hex", "utf8");
    decrypted += decipher.final("utf8");
    return decrypted;
  }
}
```

***

### **Best Practices**

#### **1. Environment Segregation**

Use separate `.env` files for different environments:

* `.env.development` – Development settings
* `.env.staging` – Staging environment
* `.env.production` – Production environment

***

#### **2. Secret Validation**

Ensure required secrets are defined:

```typescript
async function validateSecrets(character: Character): Promise<void> {
  const required = ["OPENAI_API_KEY", "SOLANA_PRIVATE_KEY"];
  const missing = required.filter((key) => !character.settings.secrets[key]);
  if (missing.length > 0) {
    throw new Error(`Missing required secrets: ${missing.join(", ")}`);
  }
}
```

***

#### **3. Git Security**

Exclude sensitive files from version control by adding the following to `.gitignore`:

```bash
.env
characters/**/secrets.json
```

***

#### **4. Secret Rotation**

Regularly rotate secrets to enhance security:

```typescript
class SecretRotation {
  private static readonly SECRET_LIFETIME = 90 * 24 * 60 * 60 * 1000; // 90 days

  async shouldRotateSecret(secretName: string): Promise<boolean> {
    const lastRotation = await this.getLastRotation(secretName);
    return Date.now() - lastRotation > SecretRotation.SECRET_LIFETIME;
  }

  async rotateSecret(secretName: string): Promise<void> {
    // Logic for secret rotation
    const newSecret = await this.generateNewSecret();
    await this.updateSecret(secretName, newSecret);
  }
}
```

***

### **Troubleshooting**

#### **Common Issues**

1. **Missing Secrets**\
   Ensure required environment variables or character-specific secrets are defined:

   ```typescript
   if (!process.env.OPENAI_API_KEY) {
     throw new Error("OpenAI API key is missing.");
   }
   ```
2. **Invalid Secret Format**\
   Validate the format of critical secrets like API keys:

   ```typescript
   function validateApiKey(key: string): boolean {
     return key.startsWith("sk-") && key.length > 20;
   }
   ```
3. **Secret Loading Errors**\
   Handle errors gracefully during secret loading:

   ```typescript
   try {
     await loadSecrets();
   } catch (error) {
     console.error("Error loading secrets:", error.message);
   }
   ```

***

### **Security Considerations**

#### **1. API Keys Handling**

* Use strong validation logic for keys.
* Rotate keys periodically to reduce risks.

***

#### **2. Access Control**

* Restrict access to sensitive secrets using a controlled list.
* Log unauthorized access attempts for monitoring.

***

#### **3. Encryption at Rest**

* Encrypt all sensitive data stored on disk.
* Use AES-256-GCM encryption for strong security.

***

### **Related Resources**

* **Configuration Guide**: General setup instructions.
* **Local Development Guide**: Best practices for local environments.
* **Infrastructure Guide**: Secure deployment practices.

***

By following these guidelines, you can manage secrets effectively and securely within the **Cyne AI** framework, ensuring robust and secure operations.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.cyne.ai/guides/credential-security.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
