Security and Privacy Best Practices
Comprehensive guide to security and privacy best practices when using Cogny, including data encryption, access controls, compliance, and secure integration patterns.
Overview
Cogny is built with security and privacy as foundational principles. This guide covers best practices for maintaining data security, ensuring privacy compliance, and implementing secure integration patterns.
Data Security
Encryption
Data at Rest:
- Algorithm: AES-256-GCM encryption
- Key Management: AWS KMS with automatic key rotation
- Scope: All stored data, including credentials, reports, and user data
Data in Transit:
- Protocol: TLS 1.3 (minimum TLS 1.2)
- Certificates: 256-bit SSL certificates
- All connections: API, web interface, and database connections
Service Account Credentials:
# Example: Securely store BigQuery credentials
import json
from cryptography.fernet import Fernet
def encrypt_credentials(credentials_json, encryption_key):
"""Encrypt service account credentials"""
f = Fernet(encryption_key)
encrypted = f.encrypt(credentials_json.encode())
return encrypted
def decrypt_credentials(encrypted_data, encryption_key):
"""Decrypt service account credentials"""
f = Fernet(encryption_key)
decrypted = f.decrypt(encrypted_data)
return json.loads(decrypted)
# Never store plaintext credentials
# Always use encrypted storage or secret managers
Access Control
Principle of Least Privilege:
BigQuery service account permissions:
# ✅ Good: Read-only access
roles/bigquery.dataViewer
roles/bigquery.jobUser
roles/bigquery.metadataViewer
# ❌ Bad: Excessive permissions
roles/bigquery.admin
roles/editor
Google Ads API permissions:
# ✅ Good: Read-only scope
https://www.googleapis.com/auth/adwords
# ❌ Bad: Excessive scope
https://www.googleapis.com/auth/cloud-platform
Role-Based Access Control (RBAC):
| Role | Permissions | Use Case |
|---|---|---|
| Viewer | Read reports, view tickets | Stakeholders, executives |
| Analyst | Create reports, manage tickets | Growth team, analysts |
| Admin | All permissions + integrations | Technical leads |
| Owner | All permissions + billing | Account owners |
API Security
API Key Management:
# Rotate API keys every 90 days
curl -X POST https://api.cogny.com/v1/api-keys/rotate \
-H "Authorization: Bearer sk_live_abc123xyz789" \
-H "Content-Type: application/json" \
-d '{"key_id": "key_xyz123"}'
IP Allowlisting (Enterprise):
# Configure IP allowlist
curl -X POST https://api.cogny.com/v1/security/ip-allowlist \
-H "Authorization: Bearer sk_live_abc123xyz789" \
-H "Content-Type: application/json" \
-d '{
"allowed_ips": [
"203.0.113.0/24",
"198.51.100.42"
],
"enabled": true
}'
Request Signing (Enterprise):
import hmac
import hashlib
import time
def sign_request(payload, api_secret):
"""Sign API request for additional security"""
timestamp = str(int(time.time()))
message = f"{timestamp}.{payload}"
signature = hmac.new(
api_secret.encode(),
message.encode(),
hashlib.sha256
).hexdigest()
return {
'X-Cogny-Signature': signature,
'X-Cogny-Timestamp': timestamp
}
# Include in API requests
headers = sign_request(json.dumps(payload), API_SECRET)
headers['Authorization'] = f'Bearer {API_KEY}'
Audit Logging
All actions are logged for security auditing:
Logged Events:
- User authentication (login, logout, failed attempts)
- API key creation, rotation, deletion
- Data warehouse connections
- Report generation
- Configuration changes
- Data exports
Access Audit Logs:
# Via API
curl -X GET "https://api.cogny.com/v1/audit-logs?limit=100&event_type=authentication" \
-H "Authorization: Bearer sk_live_abc123xyz789"
Example Audit Log Entry:
{
"id": "log_abc123",
"timestamp": "2025-02-15T10:30:00Z",
"event_type": "warehouse.connected",
"user_id": "user_456",
"user_email": "analyst@company.com",
"ip_address": "203.0.113.42",
"user_agent": "Mozilla/5.0...",
"resource_type": "warehouse",
"resource_id": "wh_123abc",
"action": "create",
"metadata": {
"warehouse_type": "bigquery",
"project_id": "company-analytics"
}
}
Privacy Compliance
GDPR Compliance
Data Subject Rights:
-
Right to Access:
# Export user data curl -X POST https://api.cogny.com/v1/privacy/data-export \ -H "Authorization: Bearer sk_live_abc123xyz789" \ -d '{"user_id": "user_456"}' -
Right to Erasure:
# Delete user data curl -X DELETE https://api.cogny.com/v1/privacy/user-data \ -H "Authorization: Bearer sk_live_abc123xyz789" \ -d '{"user_id": "user_456", "reason": "user_request"}' -
Right to Data Portability:
# Export in machine-readable format curl -X POST https://api.cogny.com/v1/privacy/data-export \ -H "Authorization: Bearer sk_live_abc123xyz789" \ -d '{"user_id": "user_456", "format": "json"}'
Data Processing Agreement (DPA):
- Available for Enterprise customers
- Defines data processing terms
- Outlines security measures
- Specifies data retention policies
PII Protection
Automatic PII Detection:
Cogny automatically detects and handles PII:
-- PII detection in queries
SELECT
REGEXP_CONTAINS(email, r'[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}') as is_email,
REGEXP_CONTAINS(phone, r'\d{3}-\d{3}-\d{4}') as is_phone,
-- Masked in reports unless explicitly enabled
FROM sensitive_table
PII Masking:
# Configure PII masking
curl -X PATCH https://api.cogny.com/v1/warehouses/wh_123abc/settings \
-H "Authorization: Bearer sk_live_abc123xyz789" \
-d '{
"pii_protection": {
"enabled": true,
"mask_emails": true,
"mask_ip_addresses": true,
"mask_phone_numbers": true,
"mask_names": false
}
}'
Anonymization:
-- Anonymize user identifiers
SELECT
TO_BASE64(SHA256(user_id)) as anonymized_user_id,
DATE_TRUNC(signup_date, MONTH) as signup_month, -- Date generalization
CASE
WHEN age < 25 THEN '18-24'
WHEN age < 35 THEN '25-34'
WHEN age < 45 THEN '35-44'
ELSE '45+'
END as age_bracket -- Age binning
FROM users
Cookie Consent
For GA4 data collection:
// Example: Cookie consent integration
window.gtag('consent', 'default', {
'analytics_storage': 'denied',
'ad_storage': 'denied'
});
// After user consent
window.gtag('consent', 'update', {
'analytics_storage': 'granted',
'ad_storage': 'granted'
});
Data Retention
Configurable Retention Policies:
# Set retention policy
curl -X PATCH https://api.cogny.com/v1/warehouses/wh_123abc/retention \
-H "Authorization: Bearer sk_live_abc123xyz789" \
-d '{
"reports": "90_days",
"audit_logs": "1_year",
"raw_data": "do_not_store"
}'
Retention Options:
30_days- 30 days90_days- 90 days (default)1_year- 1 year2_years- 2 yearsindefinite- No automatic deletiondo_not_store- Don't store raw data
Automatic Deletion:
-- Scheduled deletion of old data
DELETE FROM reports
WHERE created_at < TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 90 DAY)
AND retention_policy = '90_days'
Network Security
VPC Integration (Enterprise)
Connect to BigQuery via private networking:
# Configure VPC peering
gcloud compute networks peerings create cogny-peer \
--network=your-vpc-network \
--peer-project=cogny-production \
--peer-network=cogny-vpc
Benefits:
- Traffic doesn't traverse public internet
- Additional layer of security
- Meets compliance requirements
- Lower latency
Private Service Connect
For advanced security:
# Create Private Service Connect endpoint
gcloud compute addresses create cogny-psc-endpoint \
--global \
--purpose=PRIVATE_SERVICE_CONNECT \
--addresses=10.0.0.5 \
--network=your-vpc-network
gcloud compute forwarding-rules create cogny-psc-rule \
--global \
--network=your-vpc-network \
--address=cogny-psc-endpoint \
--target-service-attachment=projects/cogny-production/serviceAttachments/cogny-api
Firewall Rules
Restrict BigQuery access:
# Allow only Cogny IP ranges
gcloud compute firewall-rules create allow-cogny-bigquery \
--direction=INGRESS \
--priority=1000 \
--network=your-vpc-network \
--action=ALLOW \
--rules=tcp:443 \
--source-ranges=35.184.0.0/16,35.185.0.0/16 \
--target-tags=bigquery
Secure Integration Patterns
Service Account Best Practices
1. Dedicated Service Accounts:
# Create separate service accounts per environment
gcloud iam service-accounts create cogny-production
gcloud iam service-accounts create cogny-staging
gcloud iam service-accounts create cogny-development
2. Key Rotation:
# Rotate keys every 90 days
# Create new key
gcloud iam service-accounts keys create new-key.json \
--iam-account=cogny-production@project.iam.gserviceaccount.com
# Update in Cogny
# Delete old key
gcloud iam service-accounts keys delete KEY_ID \
--iam-account=cogny-production@project.iam.gserviceaccount.com
3. Key Lifecycle Management:
from datetime import datetime, timedelta
from google.cloud import iam
def check_key_age(service_account_email):
"""Check if service account keys need rotation"""
client = iam.IAMCredentialsClient()
keys = client.list_service_account_keys(
name=f"projects/-/serviceAccounts/{service_account_email}"
)
for key in keys:
age = datetime.now() - key.valid_after_time
if age > timedelta(days=90):
print(f"Key {key.name} is {age.days} days old. Rotation recommended.")
OAuth Token Management
Secure Token Storage:
import os
from google.oauth2.credentials import Credentials
# Store in environment variables or secret manager
refresh_token = os.environ.get('GOOGLE_ADS_REFRESH_TOKEN')
# Never hardcode tokens
# ❌ Bad
refresh_token = "1//abc123xyz..."
# ✅ Good
refresh_token = os.environ.get('GOOGLE_ADS_REFRESH_TOKEN')
Token Refresh:
from google.auth.transport.requests import Request
def refresh_oauth_token(credentials):
"""Refresh expired OAuth token"""
if credentials.expired:
credentials.refresh(Request())
return credentials
Webhook Security
Verify Webhook Signatures:
import hmac
import hashlib
def verify_webhook_signature(payload, signature, secret):
"""Verify webhook authenticity"""
expected_signature = hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
# Use constant-time comparison
return hmac.compare_digest(signature, expected_signature)
# In webhook handler
@app.route('/webhook/cogny', methods=['POST'])
def handle_webhook():
signature = request.headers.get('X-Cogny-Signature')
payload = request.data.decode()
if not verify_webhook_signature(payload, signature, WEBHOOK_SECRET):
return jsonify({'error': 'Invalid signature'}), 401
# Process webhook
data = json.loads(payload)
# ...
Webhook Endpoint Security:
# Use HTTPS only
# Implement rate limiting
from flask_limiter import Limiter
limiter = Limiter(
app,
default_limits=["100 per hour"]
)
@app.route('/webhook/cogny', methods=['POST'])
@limiter.limit("10 per minute")
def handle_webhook():
# Handle webhook
pass
Compliance Frameworks
SOC 2 Type II
Cogny is SOC 2 Type II compliant:
- Annual audits by independent auditors
- Continuous monitoring of security controls
- Report available upon request (Enterprise)
ISO 27001
Security management system certified to ISO 27001:
- Information security policies
- Risk assessment procedures
- Incident response protocols
GDPR
Full GDPR compliance:
- DPA available for customers
- Data processing records maintained
- Privacy by design principles
- Data subject rights support
CCPA
California Consumer Privacy Act compliance:
- Consumer rights support
- Data deletion workflows
- Privacy policy transparency
Incident Response
Security Incident Reporting
Report security concerns:
- Email: security@cogny.com
- Response Time: Within 24 hours
- PGP Key: Available at cogny.com/security
Incident Response Process
- Detection: Automated monitoring and user reports
- Assessment: Severity evaluation and impact analysis
- Containment: Immediate actions to limit impact
- Remediation: Fix vulnerabilities and restore service
- Notification: Communicate with affected users (if required)
- Post-Mortem: Root cause analysis and prevention measures
Vulnerability Disclosure
Responsible disclosure program:
- Email: security@cogny.com
- Response SLA: 48 hours
- Recognition: Security hall of fame
- Bounty: Available for critical vulnerabilities
Monitoring and Alerting
Security Monitoring
Continuous monitoring for:
- Failed authentication attempts
- Unusual API activity
- Permission changes
- Data access patterns
- Query anomalies
Alerting
Configure security alerts:
# API: Configure alerting
curl -X POST https://api.cogny.com/v1/security/alerts \
-H "Authorization: Bearer sk_live_abc123xyz789" \
-d '{
"alert_type": "unusual_activity",
"conditions": {
"failed_logins_threshold": 5,
"time_window_minutes": 15
},
"notification": {
"email": ["security@company.com"],
"slack_webhook": "https://hooks.slack.com/..."
}
}'
Best Practices Checklist
Initial Setup
- Use read-only BigQuery service account
- Enable 2FA for all Cogny user accounts
- Configure PII protection settings
- Set appropriate data retention policies
- Review and accept Data Processing Agreement
- Configure audit log retention
Ongoing Maintenance
- Rotate API keys every 90 days
- Rotate service account keys every 90 days
- Review user permissions quarterly
- Monitor audit logs for unusual activity
- Keep OAuth credentials up to date
- Review and update IP allowlists
Integration Security
- Never commit credentials to version control
- Use environment variables for secrets
- Implement webhook signature verification
- Use HTTPS for all API communications
- Implement request timeouts
- Handle errors securely (don't expose details)
Support
Security Questions
- Email: security@cogny.com
- Documentation: docs.cogny.com/security
General Support
- Email: support@cogny.com
- Response Time: 24 hours (Standard), 4 hours (Enterprise)
Next Steps
- BigQuery Service Account Setup - Secure BigQuery connection
- Google Ads API Setup - Secure OAuth configuration
- API Authentication - API security best practices
Resources
- Security Portal: cogny.com/security
- Privacy Policy: cogny.com/privacy
- Terms of Service: cogny.com/terms
- Status Page: status.cogny.com
Talk to Our Technical Team
Schedule a technical consultation to discuss your integration requirements and implementation strategy.
Schedule Demo