보안 가이드
OpenClaw 사용 시 API 키, 권한, 데이터 프라이버시를 안전하게 관리하는 방법을 알아봅니다.
API 키 관리
환경 변수 사용
# .bashrc 또는 .zshrc
export OPENCLAW_API_KEY="sk-..."
export ANTHROPIC_API_KEY="sk-..."
export SLACK_BOT_TOKEN="xoxb-..."
openclaw.json에 API 키를 직접 입력하지 않습니다:
{
"apiKey": "${OPENCLAW_API_KEY}"
}
.env 파일
# .env (반드시 .gitignore에 추가)
OPENCLAW_API_KEY=sk-ant-...
ANTHROPIC_API_KEY=sk-...
SLACK_BOT_TOKEN=xoxb-...
TELEGRAM_BOT_TOKEN=123456:ABC-...
import dotenv from 'dotenv';
dotenv.config();
export const config = {
openclawApiKey: process.env.OPENCLAW_API_KEY,
anthropicApiKey: process.env.ANTHROPIC_API_KEY
};
AWS Secrets Manager 활용
import { SecretsManagerClient, GetSecretValueCommand } from '@aws-sdk/client-secrets-manager';
export async function getSecret(secretName) {
const client = new SecretsManagerClient({ region: 'us-east-1' });
const response = await client.send(
new GetSecretValueCommand({ SecretId: secretName })
);
return JSON.parse(response.SecretString);
}
권한 관리
최소 권한 원칙
skills:
permissions:
file-read:
allowedPaths:
- "${HOME}/.openclaw/workspace"
- "/tmp"
deniedPaths:
- "/etc"
- "/var"
- "${HOME}/.ssh"
file-write:
allowedPaths:
- "${HOME}/.openclaw/workspace"
- "/tmp"
deniedPaths:
- "/etc"
- "/bin"
채널별 권한
channels:
slack:
botToken: "${SLACK_BOT_TOKEN}"
scopes:
- "chat:write"
- "channels:read"
- "im:read"
# admin, files:write 등 위험한 권한은 제외
데이터 프라이버시
민감 정보 마스킹
export function sanitizeData(data) {
const sensitivePatterns = {
email: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g,
phone: /\d{3}-\d{4}-\d{4}/g,
apiKey: /sk-[a-zA-Z0-9]{48}/g,
creditCard: /\d{4}-\d{4}-\d{4}-\d{4}/g
};
let sanitized = JSON.stringify(data);
for (const [type, pattern] of Object.entries(sensitivePatterns)) {
sanitized = sanitized.replace(pattern, `[REDACTED:${type}]`);
}
return JSON.parse(sanitized);
}
메모리에서의 프라이버시
sessions:
memory:
excludePatterns:
- "password"
- "비밀번호"
- "카드번호"
masking:
enabled: true
patterns:
- regex: "\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b"
replacement: "***@***.***"
네트워크 보안
HTTPS 강제 사용
export function enforceHttps(url) {
if (!url.startsWith('https://')) {
throw new Error('HTTPS만 허용됩니다');
}
return url;
}
Rate Limiting
rateLimits:
anthropic:
requestsPerMinute: 60
tokensPerMinute: 40000
slack:
messagesPerMinute: 100
telegram:
messagesPerSecond: 30
워크스페이스 보안
workspace:
security:
allowSymlinks: false
allowParentDirectoryAccess: false
allowExecutableFiles: false
ignoreHiddenFiles: true
파일 시스템 권한:
chmod 700 ~/.openclaw/
chmod 600 ~/.openclaw/openclaw.json
chmod 700 ~/.openclaw/workspace/
감사 및 로깅
logging:
security:
enabled: true
path: "~/.openclaw/security.log"
events:
- "login_attempt"
- "permission_denied"
- "api_call"
- "file_access"
retentionDays: 90
로그에서 민감 정보를 제거합니다:
export function sanitizeLog(data) {
const sensitiveKeys = ['password', 'token', 'apiKey', 'secret'];
const sanitized = { ...data };
for (const key of sensitiveKeys) {
if (sanitized[key]) {
sanitized[key] = '[REDACTED]';
}
}
return sanitized;
}
보안 체크리스트
배포 전 확인:
- API 키가 하드코딩되지 않음
.env가.gitignore에 포함됨- 최소 권한 원칙이 적용됨
- 민감 정보 마스킹이 활성화됨
- HTTPS만 사용함
- Rate limiting이 설정됨
- 보안 로그가 활성화됨
- 파일 권한이 적절히 설정됨
참고: