This guide explains how to secure your CGC installation, especially when exposing it to the internet.
- Security Overview
- Quick Start: Secure Setup
- API Key Management
- Rate Limiting
- Data Protection
- Network Security
- Best Practices
- Security Configuration
CGC includes multiple layers of security:
| Layer | What it protects against |
|---|---|
| API Keys | Unauthorized access |
| Rate Limiting | Abuse and denial of service |
| SQL Validation | SQL injection attacks |
| Path Validation | Directory traversal attacks |
| Security Headers | XSS, clickjacking, MIME sniffing |
| Scenario | Security Level |
|---|---|
| Local testing only | Optional |
| Local network/team use | Recommended |
| Internet access (ngrok, etc.) | Required |
| Production deployment | Required |
The secure server has all protections enabled by default:
cgc serve --secure
You'll see:
Starting secure CGC API server on 127.0.0.1:8420
Authentication: REQUIRED
Rate limiting: ENABLED
Since authentication is required, you need to create a key first. Temporarily disable auth:
Windows (Command Prompt):
set CGC_REQUIRE_AUTH=false
cgc serve --secure
Windows (PowerShell):
$env:CGC_REQUIRE_AUTH = "false"
cgc serve --secure
Mac/Linux:
CGC_REQUIRE_AUTH=false cgc serve --secure
With the server running, open your browser to:
http://localhost:8420/docs
Find the POST /admin/api-keys endpoint and click "Try it out".
Fill in:
- name:
admin(or your preferred name) - permissions:
*,admin(full access including admin) - expires_days:
365(or leave blank for no expiration)
Click "Execute".
Important: Copy the API key from the response! It looks like:
cgc_lGlmobBzC2ReZZZq...
This key is only shown once. Save it somewhere safe!
Stop the server (Ctrl+C) and restart normally:
cgc serve --secure
Try accessing the API with your key:
curl -H "X-API-Key: cgc_your_key_here" http://localhost:8420/sources
You should see a list of sources (empty if none connected yet).
Without the key:
curl http://localhost:8420/sources
You'll get an authentication error.
Keys can have different permission levels:
Full Access (Admin):
permissions: *,admin
Read Only:
permissions: read
SQL Only (no file access):
permissions: sql:read
Specific Sources:
allowed_sources: mydb,documents
| Property | Description |
|---|---|
| name | Human-readable identifier |
| permissions | What the key can do |
| expires_days | When the key expires (optional) |
| allowed_sources | Which sources the key can access |
If a key is compromised:
- Go to
http://localhost:8420/docs - Use the admin endpoints to list and revoke keys
- Create new keys for affected users
- Never share keys in code repositories or public places
- Use environment variables instead of hardcoding keys
- Create separate keys for each user or application
- Set expiration dates for temporary access
- Regularly rotate keys for sensitive applications
Rate limiting prevents abuse by limiting how many requests can be made.
| Setting | Default | Description |
|---|---|---|
| Requests per window | 100 | Maximum requests allowed |
| Window size | 60 seconds | Time period for counting |
This means: 100 requests per minute per IP address.
Every response includes these headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1705312800
- Limit: Maximum requests in the window
- Remaining: Requests left in current window
- Reset: Unix timestamp when the window resets
If you exceed the limit, you'll receive:
HTTP 429 Too Many Requests
{
"error": "Rate limit exceeded",
"message": "Too many requests. Limit: 100 per 60s"
}
The response includes a Retry-After header telling you when to try again.
Set via environment variables:
CGC_RATE_LIMIT_REQUESTS=200
CGC_RATE_LIMIT_WINDOW=60
Or in the config file (~/.cgc/security.json):
{
"rate_limit_enabled": true,
"rate_limit_requests": 200,
"rate_limit_window_seconds": 60
}Different API keys can have different limits:
{
"name": "high-volume-client",
"rate_limit": 1000
}CGC blocks dangerous SQL keywords by default:
Blocked:
- DROP, DELETE, TRUNCATE
- ALTER, CREATE
- INSERT, UPDATE
- GRANT, REVOKE
- EXEC, EXECUTE
- Comments (--, /*, */)
Allowed:
- SELECT queries only
If you need write access, grant sql:write permission to specific keys.
CGC blocks access to sensitive paths:
Always Blocked:
- System directories (
/etc,/var,C:\Windows) - Home directories (
/home,C:\Users) - Hidden files (
.env,.git,.ssh) - Credential files (
id_rsa,credentials,secrets)
Allowed Paths:
By default, any path not on the blocked list is allowed. For stricter control, set allowed paths:
{
"allowed_paths": [
"C:\\Data\\Reports",
"C:\\Data\\Documents"
]
}Sensitive information is automatically masked in logs and error messages:
Before: Connection failed: postgresql://admin:secret123@localhost/db
After: Connection failed: postgresql://admin:****@localhost/db
By default, CGC only accepts connections from your local machine:
bind_host: 127.0.0.1
This means other computers on your network can't access it.
To allow access from other machines:
Local Network:
CGC_BIND_HOST=0.0.0.0 cgc serve --secure
Caution: This exposes CGC to your entire network.
For internet access, use ngrok:
-
Install ngrok from https://ngrok.com
-
Start CGC with security enabled:
cgc serve --secure -
Start ngrok:
ngrok http 8420 -
Use the ngrok URL (like
https://abc123.ngrok.io)
Important: Always use the secure server when exposing to the internet!
By default, only localhost origins are allowed:
{
"allowed_origins": ["http://localhost:*"]
}To allow specific domains:
{
"allowed_origins": [
"https://your-app.com",
"https://n8n.your-company.com"
]
}Never use * in production! This allows any website to access your API.
- Use
cgc serve(without security) for quick testing - Use
cgc serve --securewhen testing security features - Create a dedicated development API key
- Always use
cgc serve --secure - Create separate keys for each team member
- Use permission restrictions based on role
- Set key expiration (e.g., 30-90 days)
- Always use
cgc serve --secure - Use strong, unique API keys
- Set up ngrok with authentication if possible
- Monitor access logs regularly
- Set aggressive rate limits
- Restrict allowed paths strictly
- Consider a VPN instead of public exposure
- Run behind a reverse proxy (nginx, traefik)
- Use HTTPS (the proxy handles SSL)
- Implement IP whitelisting if possible
- Set up log aggregation and alerting
- Regular security audits
- Keep CGC updated
Create ~/.cgc/security.json:
{
"require_auth": true,
"api_keys_file": "~/.cgc/api_keys.json",
"rate_limit_enabled": true,
"rate_limit_requests": 100,
"rate_limit_window_seconds": 60,
"allow_raw_sql": false,
"sql_max_rows": 10000,
"sql_timeout_seconds": 30,
"blocked_sql_keywords": [
"DROP", "DELETE", "TRUNCATE", "ALTER", "CREATE",
"INSERT", "UPDATE", "GRANT", "REVOKE", "EXEC"
],
"allowed_paths": [],
"blocked_paths": [
"/etc", "/var", "/root", "/home",
"C:\\Windows", "C:\\Program Files",
".env", ".git", ".ssh", "credentials", "secrets"
],
"max_file_size_mb": 100,
"allowed_origins": ["http://localhost:*"],
"bind_host": "127.0.0.1",
"bind_port": 8420,
"max_request_size_mb": 10,
"request_timeout_seconds": 60,
"log_requests": true,
"log_queries": true,
"mask_credentials": true
}All settings can be overridden with environment variables:
| Variable | Description |
|---|---|
CGC_REQUIRE_AUTH |
Require API keys (true/false) |
CGC_BIND_HOST |
Server IP address |
CGC_BIND_PORT |
Server port |
CGC_RATE_LIMIT_ENABLED |
Enable rate limiting |
CGC_RATE_LIMIT_REQUESTS |
Requests per window |
CGC_RATE_LIMIT_WINDOW |
Window size in seconds |
CGC_ALLOW_RAW_SQL |
Allow non-SELECT queries |
CGC_SQL_MAX_ROWS |
Maximum result rows |
CGC_ALLOWED_PATHS |
Comma-separated allowed paths |
CGC_BLOCKED_PATHS |
Comma-separated blocked paths |
CGC_ALLOWED_ORIGINS |
Comma-separated CORS origins |
CGC_LOG_REQUESTS |
Log all requests |
CGC_LOG_QUERIES |
Log SQL queries |
- Immediately revoke the compromised key
- Create a new key for the affected user
- Review access logs for suspicious activity
- Change any credentials the key had access to
- Check rate limit logs for unusual patterns
- Review blocked requests (SQL injection attempts, etc.)
- Temporarily increase rate limiting if under attack
- Consider IP blocking at the network level
- Watch for CGC updates that address security issues
- Apply security patches promptly
- Review the changelog for security-related changes
- API Reference - Detailed endpoint documentation
- CLI Reference - Command-line usage
- Technical Overview - How CGC works