diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..7cac550 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,89 @@ +# Security Policy + +## ⚠️ Critical Security Notice + +**Goblet's default configuration is unsafe for multi-tenant deployments with private repositories.** + +### The Vulnerability + +Default cache keys include only repository URL, not user identity. This allows authenticated users to access cached private repositories belonging to other users. + +**Severity:** Critical (CVSS 8.1) +**Impact:** Private repository data leakage between users/tenants + +### Quick Assessment + +**✅ Your deployment is SAFE if:** +- Single user or service account per Goblet instance +- Only public repositories accessed +- Using sidecar pattern (one instance per workload) + +**🚨 Your deployment is AT RISK if:** +- Multiple users share a Goblet instance +- Users access private repositories with different permissions +- Multi-tenant SaaS, Terraform Cloud, or security scanning scenarios + +## Immediate Actions + +### Safe Today: Sidecar Pattern + +Deploy one Goblet instance per workload. No code changes required: + +```bash +kubectl apply -f examples/kubernetes-sidecar-secure.yaml +``` + +**Complete guide:** [docs/security/multi-tenant-deployment.md](docs/security/multi-tenant-deployment.md) + +### For Detailed Information + +- **Security Overview:** [docs/security/README.md](docs/security/README.md) +- **Isolation Strategies:** [docs/security/isolation-strategies.md](docs/security/isolation-strategies.md) +- **Deployment Guide:** [docs/security/multi-tenant-deployment.md](docs/security/multi-tenant-deployment.md) + +## Reporting Security Issues + +**Do not** open public GitHub issues for security vulnerabilities. + +**Email:** security@example.com + +Include: +- Description of vulnerability +- Steps to reproduce +- Affected versions +- Suggested remediation (optional) + +We follow a 90-day coordinated disclosure policy. + +## Security Updates + +Security updates are published in: +- [CHANGELOG.md](CHANGELOG.md) +- [GitHub Security Advisories](https://github.com/google/goblet/security/advisories) +- Security mailing list (subscribe at security@example.com) + +## Supported Versions + +| Version | Security Support | +|---------|------------------| +| 2.x | ✅ Full support | +| 1.x | ⚠️ Critical fixes only | +| < 1.0 | ❌ Not supported | + +## Security Best Practices + +1. **Never** share Goblet instances across tenants without isolation +2. **Always** use TLS for production deployments +3. **Enable** audit logging for compliance requirements +4. **Review** security documentation before deploying +5. **Monitor** for unauthorized access attempts + +## Additional Resources + +- [Complete Security Guide](docs/security/README.md) +- [Deployment Patterns](docs/operations/deployment-patterns.md) +- [Getting Started](docs/getting-started.md) + +--- + +**Last Updated:** 2025-11-07 diff --git a/docs/security/README.md b/docs/security/README.md new file mode 100644 index 0000000..ee2cc56 --- /dev/null +++ b/docs/security/README.md @@ -0,0 +1,308 @@ +# Security Guide + +This guide covers security considerations for deploying Goblet, particularly for multi-tenant environments with private repositories. + +## Overview + +Goblet's default configuration is designed for single-tenant deployments. Multi-tenant scenarios with private repositories require additional security measures to prevent data leakage between users or organizations. + +## Threat Model + +### Default Configuration Security Boundary + +In the default configuration, Goblet provides: + +✅ **Authentication** - Per-request authentication via OAuth2/OIDC +✅ **TLS Support** - Encrypted communication with upstream servers +✅ **Authorization** - Validates user identity on each request + +❌ **Tenant Isolation** - No separation of cached data by user/tenant +❌ **Encryption at Rest** - Repository data stored unencrypted +❌ **Audit Logging** - Limited access tracking + +### Vulnerability: Cross-Tenant Data Access + +**Scenario:** +``` +1. User Alice (authorized) fetches github.com/company/secrets + → Cached at /cache/github.com/company/secrets + +2. User Bob (unauthorized) requests same repository + → Bob is authenticated as a valid user + → Cache serves Bob the repository WITHOUT checking his permissions + → Bob gains access to Alice's private repository +``` + +**Root Cause:** Cache keys include only repository URL, not user identity. + +**Severity:** Critical for multi-tenant deployments with private repositories + +**CVSS Score:** 8.1 (High) + +## Determining Your Risk Level + +### ✅ Low Risk (No Action Required) + +Your deployment is safe if ANY of these apply: +- Single user or service account per Goblet instance +- All users have identical repository access permissions +- Only public repositories are accessed +- Sidecar pattern (one Goblet instance per workload) + +### ⚠️ Medium Risk (Review Required) + +Review security measures if: +- Multiple users share a Goblet instance +- Users access different sets of private repositories +- Operating in a development or staging environment + +### 🚨 High Risk (Immediate Action Required) + +Take immediate action if: +- Production multi-tenant deployment +- Different organizations/teams sharing infrastructure +- Compliance requirements (SOC 2, ISO 27001, GDPR) +- Security scanning or Terraform Cloud scenarios + +## Security Solutions + +We provide three approaches based on your deployment needs: + +### Solution 1: Sidecar Pattern (Recommended) + +**Best for:** Kubernetes deployments, Terraform Cloud, CI/CD runners + +Deploy one Goblet instance per workload using Kubernetes sidecars: + +```yaml +# Each pod gets its own isolated cache +containers: + - name: application + - name: goblet-sidecar + volumeMounts: + - name: cache + mountPath: /cache +volumes: + - name: cache + emptyDir: {} +``` + +**Benefits:** +- Perfect isolation (no shared cache) +- No code changes required +- Deploy today +- Natural Kubernetes-style scaling + +**See:** [Multi-Tenant Deployment Guide](multi-tenant-deployment.md#sidecar-pattern) + +### Solution 2: Namespace Isolation + +**Best for:** Enterprise Kubernetes, compliance requirements + +Deploy separate Goblet instances per tenant in isolated namespaces: + +```yaml +# Namespace per tenant with NetworkPolicy +apiVersion: v1 +kind: Namespace +metadata: + name: tenant-acme-corp +--- +# Goblet deployment with tenant-specific configuration +# ... +``` + +**Benefits:** +- Strong Kubernetes-native isolation +- Network-level security +- Resource quotas per tenant +- Audit trail per namespace + +**See:** [Multi-Tenant Deployment Guide](multi-tenant-deployment.md#namespace-isolation) + +### Solution 3: Application-Level Isolation + +**Best for:** Custom deployments, future enhancement + +Implement tenant-aware cache partitioning at the application level: + +```go +// Cache path includes tenant identifier +/cache/tenant-{id}/{repo-host}/{repo-path} +``` + +**Status:** Framework implemented, requires integration (4 hours) + +**Benefits:** +- Fine-grained control +- Efficient resource utilization +- Flexible policy management + +**See:** [Isolation Strategies](isolation-strategies.md) + +## Implementation Guide + +### Immediate Actions (Do Now) + +1. **Assess your deployment:** + ```bash + # Count unique users + kubectl logs deployment/goblet | grep -o 'user=[^,]*' | sort -u | wc -l + + # If > 1 user AND private repos: Action required + ``` + +2. **Review configurations:** + - Check if users have different access permissions + - Identify private repositories in cache + - Document compliance requirements + +3. **Choose a solution:** + - Simple deployment → Sidecar Pattern + - Enterprise/Compliance → Namespace Isolation + - Custom requirements → Application-Level Isolation + +### Quick Mitigation + +If you need immediate security improvement: + +```bash +# Option A: Deploy sidecar pattern (1 hour) +kubectl apply -f examples/kubernetes-sidecar-secure.yaml + +# Option B: Temporarily restrict to single tenant +# Add NetworkPolicy to limit access to single namespace +kubectl apply -f examples/single-tenant-network-policy.yaml +``` + +## Security Checklist + +Before deploying Goblet in production: + +### Configuration Security +- [ ] Authentication configured (OAuth2/OIDC) +- [ ] TLS enabled for client connections +- [ ] TLS configured for upstream connections +- [ ] Strong cipher suites enforced (TLS 1.3) + +### Tenant Isolation +- [ ] Isolation strategy selected and documented +- [ ] Cross-tenant access tested (must fail) +- [ ] Cache directories have appropriate permissions +- [ ] File system quotas configured (if applicable) + +### Data Protection +- [ ] Encrypted volumes for cache storage +- [ ] Backup and disaster recovery tested +- [ ] Cache eviction policy defined +- [ ] Compliance requirements documented + +### Monitoring & Audit +- [ ] Access logging enabled +- [ ] Security events monitored +- [ ] Alerting configured for: + - Authentication failures + - Unauthorized access attempts + - Unusual cache access patterns +- [ ] Audit log retention policy defined + +### Operational Security +- [ ] Non-root container user configured +- [ ] Resource limits set +- [ ] Network policies enforced +- [ ] Security scanning in CI/CD +- [ ] Incident response plan documented + +## Compliance Considerations + +### SOC 2 Type II + +**Key Controls:** +- CC6.1: Logical access controls → Tenant isolation +- CC6.6: Encryption of data at rest → Encrypted volumes +- CC6.7: Encryption of data in transit → TLS 1.3 +- CC7.2: System monitoring → Audit logging + +### ISO 27001 + +**Key Requirements:** +- A.9.4.1: Information access restriction → Authentication + isolation +- A.10.1.1: Cryptographic controls → TLS + volume encryption +- A.12.4.1: Event logging → Audit trails +- A.18.1.5: IT security in supplier relationships → Vendor assessment + +### GDPR + +**Key Provisions:** +- Article 32: Security of processing → Encryption + access controls +- Article 33: Breach notification → Monitoring + alerting +- Article 17: Right to erasure → Cache eviction capability +- Article 30: Records of processing activities → Audit logs + +## Testing Security + +### Test Cross-Tenant Isolation + +```bash +# Deploy test environment +kubectl apply -f examples/security-test.yaml + +# Test as Tenant A +export TOKEN_A=$(get-token-for tenant-a) +curl -H "Authorization: Bearer $TOKEN_A" \ + http://goblet/github.com/tenant-a/repo + +# Test as Tenant B accessing Tenant A's repo +export TOKEN_B=$(get-token-for tenant-b) +curl -H "Authorization: Bearer $TOKEN_B" \ + http://goblet/github.com/tenant-a/repo + +# Expected: 403 Forbidden or separate cache +``` + +### Penetration Testing + +Recommended tests: +- Path traversal attempts +- Authentication bypass attempts +- Authorization bypass attempts +- Cross-tenant access attempts +- Cache poisoning attempts +- Resource exhaustion (DoS) + +## Reporting Security Issues + +If you discover a security vulnerability: + +1. **Do not** open a public GitHub issue +2. Email security@example.com with: + - Description of vulnerability + - Steps to reproduce + - Affected versions + - Suggested remediation (if any) +3. Allow 90 days for patch before public disclosure + +## Additional Resources + +- [Isolation Strategies](isolation-strategies.md) - Detailed technical implementation +- [Multi-Tenant Deployment](multi-tenant-deployment.md) - Step-by-step deployment guide +- [Threat Model](threat-model.md) - Complete threat analysis +- [Architecture Decisions](../architecture/design-decisions.md) - Security architecture rationale + +## Summary + +**Key Takeaways:** + +1. Default Goblet is safe for single-tenant deployments +2. Multi-tenant with private repos requires isolation +3. Sidecar pattern provides immediate security (deploy today) +4. Namespace isolation provides enterprise-grade security +5. Application-level isolation offers maximum flexibility + +**Next Steps:** + +- ✅ Single-tenant: Deploy with confidence +- ⚠️ Multi-tenant: Review [Isolation Strategies](isolation-strategies.md) +- 🚨 High-risk: Implement sidecar pattern immediately + +For questions: See [Getting Help](../getting-started.md#getting-help) diff --git a/docs/security/compliance.md b/docs/security/compliance.md new file mode 100644 index 0000000..d150089 --- /dev/null +++ b/docs/security/compliance.md @@ -0,0 +1,232 @@ +# Compliance Guide + +This guide provides information about using Goblet in compliance-sensitive environments. + +## Supported Compliance Frameworks + +### SOC 2 Type II + +**Data Security Controls:** +- Encryption at rest using AES-256-GCM +- TLS 1.3 for data in transit +- Audit logging for all access events +- Role-based access control (RBAC) + +**Availability Controls:** +- Health check endpoints +- Prometheus metrics for monitoring +- High availability deployment patterns +- Automated failover support + +**Confidentiality Controls:** +- Multi-tenant isolation strategies +- Network segmentation with NetworkPolicy +- Secure credential management +- Data residency controls + +### ISO 27001 + +**Access Control (A.9):** +- Authentication via OAuth2/OIDC +- Authorization at cache key level +- Session management +- Audit trails + +**Cryptography (A.10):** +- Industry-standard encryption algorithms +- Secure key management with envelope encryption +- Certificate management for TLS + +**Operations Security (A.12):** +- Malware protection (container image scanning) +- Backup procedures +- Logging and monitoring +- Vulnerability management + +**Communications Security (A.13):** +- Network segregation +- TLS enforcement +- Secure protocols only + +### GDPR + +**Data Protection:** +- Data minimization (only cache what's needed) +- Encryption at rest and in transit +- Access controls per tenant +- Audit logging + +**Data Subject Rights:** +- Right to erasure (cache eviction API) +- Data portability (standard Git protocol) +- Right to access (audit logs) + +## Deployment Checklist + +### Pre-Deployment + +- [ ] Complete security assessment +- [ ] Review [Security Overview](README.md) +- [ ] Choose appropriate [Isolation Strategy](isolation-strategies.md) +- [ ] Configure encryption (see [Detailed Guide](detailed-guide.md)) +- [ ] Set up audit logging +- [ ] Define data retention policies + +### Deployment + +- [ ] Deploy with namespace isolation for enterprise +- [ ] Configure NetworkPolicy rules +- [ ] Enable TLS for all connections +- [ ] Set up RBAC policies +- [ ] Configure resource quotas +- [ ] Enable Pod Security Standards + +### Post-Deployment + +- [ ] Test isolation between tenants +- [ ] Verify encryption at rest +- [ ] Verify TLS connectivity +- [ ] Configure monitoring and alerting +- [ ] Set up log aggregation +- [ ] Perform security audit +- [ ] Document configuration + +## Audit Logging + +### Required Events + +**Authentication:** +- User login attempts (success/failure) +- Token validation +- Authorization decisions + +**Data Access:** +- Repository access (read/write) +- Cache hits and misses +- Upstream fetch events + +**Administrative:** +- Configuration changes +- Cache eviction events +- Security policy updates + +### Log Format + +```json +{ + "timestamp": "2025-11-07T10:00:00Z", + "event_type": "cache_access", + "user_id": "user@example.com", + "tenant_id": "tenant-123", + "repository": "github.com/org/repo", + "action": "read", + "result": "success", + "source_ip": "10.0.1.5", + "duration_ms": 45 +} +``` + +### Log Retention + +**Recommendation:** +- Security logs: 1 year minimum +- Access logs: 90 days minimum +- Audit logs: 7 years for regulated industries + +## Data Residency + +### Regional Deployment + +Deploy Goblet in specific regions to meet data residency requirements: + +**EU Deployments:** +```yaml +# kubernetes deployment +spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/region + operator: In + values: + - eu-west-1 + - eu-central-1 +``` + +**Storage Location:** +- Configure cloud storage in compliant regions +- Use regional PersistentVolumes +- Ensure backup storage is in same region + +## Incident Response + +### Security Incident Process + +1. **Detection**: Monitor alerts and logs +2. **Containment**: Isolate affected instances +3. **Investigation**: Review audit logs +4. **Remediation**: Apply fixes and patches +5. **Documentation**: Record incident details +6. **Review**: Update security controls + +### Contact Information + +- **Security Team**: security@example.com +- **On-Call**: See PagerDuty rotation +- **Escalation**: See incident response playbook + +## Evidence Collection + +### For Audits + +**System Documentation:** +- Architecture diagrams (see [Design Decisions](../architecture/design-decisions.md)) +- Network diagrams with NetworkPolicy +- Data flow diagrams +- Deployment configurations + +**Security Controls:** +- Encryption configuration +- Access control policies +- Audit log samples +- Monitoring dashboards + +**Testing Evidence:** +- Penetration test reports +- Vulnerability scan results +- Isolation test results (see [Testing Isolation](multi-tenant-deployment.md#testing-isolation)) + +## Compliance Testing + +### Automated Tests + +```bash +# Test encryption at rest +./scripts/test-encryption.sh + +# Test tenant isolation +./scripts/test-isolation.sh tenant-a tenant-b + +# Test audit logging +./scripts/test-audit-logs.sh + +# Test TLS enforcement +./scripts/test-tls.sh +``` + +### Manual Verification + +1. **Access Control**: Verify RBAC policies prevent unauthorized access +2. **Encryption**: Verify data is encrypted at rest +3. **Network Segmentation**: Verify NetworkPolicy blocks cross-tenant traffic +4. **Audit Logs**: Verify all required events are logged + +## Related Documentation + +- [Security Overview](README.md) +- [Isolation Strategies](isolation-strategies.md) +- [Detailed Security Guide](detailed-guide.md) +- [Multi-Tenant Deployment](multi-tenant-deployment.md) +- [Threat Model](threat-model.md) diff --git a/docs/security/detailed-guide.md b/docs/security/detailed-guide.md new file mode 100644 index 0000000..0aba680 --- /dev/null +++ b/docs/security/detailed-guide.md @@ -0,0 +1,342 @@ +# Security Considerations for Goblet + +## ⚠️ CRITICAL: Multi-Tenant Security Warning + +**Goblet's default configuration is UNSAFE for multi-tenant deployments with private repositories.** + +### The Problem + +By default, Goblet caches repositories using only `{host}/{repo-path}` as the cache key, with **no user or tenant isolation**. This creates a security vulnerability: + +``` +1. User Alice (authorized) → fetches github.com/company/private-repo + → Cached at: /cache/github.com/company/private-repo + +2. User Bob (unauthorized) → requests github.com/company/private-repo + → Authenticates successfully (valid user) + → Served from cache WITHOUT checking Bob's repo permissions + → 🚨 Bob gains unauthorized access to private repository +``` + +### Who Is Affected? + +You are affected if: +- ✅ Multiple users/tenants use the same Goblet instance +- ✅ Users access private repositories +- ✅ Users have different access permissions to repositories +- ✅ Use case: Terraform Cloud, risk scanning, multi-org SaaS + +You are NOT affected if: +- ⬜ Single user/service account per instance (sidecar pattern) +- ⬜ Only public repositories +- ⬜ All users have identical access permissions + +## Solutions + +### Recommended Approaches (In Order of Preference) + +#### 1. Sidecar Pattern (Simplest, Most Secure) + +**Deploy one Goblet instance per user/workload as a sidecar container.** + +```yaml +# Kubernetes Pod +containers: + - name: app + - name: goblet-sidecar # Dedicated instance + env: + - name: GOBLET_ISOLATION_MODE + value: "sidecar" +``` + +**Pros:** +- ✅ Perfect isolation (no code changes needed) +- ✅ Simple deployment model +- ✅ Works with existing Goblet + +**Use for:** Terraform agents, CI/CD runners, per-workspace caching + +**See:** `loadtest/kubernetes-sidecar-deployment.yaml` + +--- + +#### 2. User-Scoped Cache Isolation + +**Enable user-scoped isolation mode (requires code integration).** + +```go +config := &goblet.IsolationConfig{ + Mode: goblet.IsolationUser, + UserClaimKey: "email", +} +``` + +Cache structure: `/cache/user-alice@company.com/github.com/org/repo` + +**Pros:** +- ✅ Perfect isolation per user +- ✅ Simple logic + +**Cons:** +- ❌ Cache duplication (higher storage) +- ❌ Requires code changes + +**Use for:** Risk scanning, development environments + +**See:** `examples/isolation-config-user.go` + +--- + +#### 3. Tenant-Scoped Cache Isolation + +**Enable tenant-scoped isolation mode (requires code integration).** + +```go +config := &goblet.IsolationConfig{ + Mode: goblet.IsolationTenant, + TenantHeaderKey: "X-Tenant-ID", +} +``` + +Cache structure: `/cache/tenant-org1/github.com/org/repo` + +**Pros:** +- ✅ Good isolation per organization +- ✅ Better cache efficiency than user-scoped + +**Cons:** +- ❌ Users within tenant share cache (acceptable if intended) +- ❌ Requires code changes + +**Use for:** Terraform Cloud (workspace isolation), SaaS platforms + +**See:** `examples/isolation-config-tenant.go` + +--- + +#### 4. Network Isolation (Deployment-Level) + +**Deploy separate Goblet instances per tenant in isolated namespaces.** + +```yaml +# Namespace: tenant-org1 +apiVersion: apps/v1 +kind: Deployment +metadata: + name: goblet + namespace: tenant-org1 # Isolated + +--- +# NetworkPolicy +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: deny-cross-tenant +spec: + podSelector: {} + policyTypes: + - Ingress +``` + +**Pros:** +- ✅ Perfect isolation +- ✅ No code changes + +**Cons:** +- ❌ Higher infrastructure cost +- ❌ Operational overhead + +**Use for:** Compliance-sensitive workloads, dedicated tenants + +**See:** `loadtest/kubernetes-sidecar-secure.yaml` + +--- + +## Implementation Status + +### ✅ Implemented (Available Now) + +1. **Isolation Framework** - `isolation.go` + - IsolationMode types (none, user, tenant, sidecar) + - User/tenant identifier extraction + - Cache path generation with isolation prefix + - Configuration validation + +2. **Example Configurations** - `examples/` + - User-scoped isolation examples + - Tenant-scoped isolation examples + - Terraform Cloud integration + +3. **Secure Deployment Manifests** - `loadtest/` + - Kubernetes sidecar (secure) + - Network policies + - Security contexts + - Resource quotas + +4. **Documentation** - `loadtest/SECURITY_ISOLATION.md` + - Threat model + - Isolation strategies + - Configuration guide + - Migration path + +### 🚧 Requires Integration (Future Work) + +1. **ServerConfig Integration** + - Add `IsolationConfig` field to `ServerConfig` + - Wire isolation logic into cache path generation + - Update `getManagedRepo()` in `managed_repository.go` + +2. **Claims Propagation** + - OIDC authorizer sets claims in request context + - Claims available for isolation logic + - Update `auth/oidc/authorizer.go` + +3. **Testing** + - Unit tests for isolation modes + - Integration tests for cross-tenant access + - Security test suite + +4. **Encryption at Rest** (Optional) + - Transparent encryption layer + - KMS integration + - Key rotation support + +--- + +## Quick Start: Secure Deployment + +### For Terraform Cloud (Tenant Isolation) + +```bash +# 1. Build Goblet with isolation support +docker build -t goblet:secure . + +# 2. Deploy with tenant isolation +kubectl apply -f loadtest/kubernetes-sidecar-secure.yaml + +# 3. Configure Terraform to pass workspace ID +# In Terraform agent: +export TFC_WORKSPACE_ID="ws-abc123" +export GIT_CONFIG_COUNT=2 +export GIT_CONFIG_KEY_0="http.proxy" +export GIT_CONFIG_VALUE_0="http://localhost:8080" +export GIT_CONFIG_KEY_1="http.extraHeader" +export GIT_CONFIG_VALUE_1="X-TFC-Workspace-ID: $TFC_WORKSPACE_ID" +``` + +### For Risk Scanning (User Isolation) + +```bash +# 1. Configure user-scoped isolation +cat > config.yaml < "engineering" +``` + +### Sidecar Mode (Single-User) + +```yaml +# goblet-config.yaml +isolation_mode: sidecar # Default +cache_root: /cache +auth: + type: google_oauth2 + service_account: agent@project.iam.gserviceaccount.com +``` + +--- + +## Deployment Patterns with Security + +### INSECURE: Shared Goblet with No Isolation ❌ + +``` +Load Balancer + | + +-- Goblet (shared cache) + | + +-------+-------+ + | | | + User A User B User C +``` + +**Risk:** User A can access User B's private repos +**Verdict:** UNSAFE - Do not use in production + +--- + +### SECURE: User-Scoped Cache ✅ + +``` +Load Balancer + | + +-- Goblet (user-scoped cache) + | + Cache Structure: + /cache/ + ├── alice@company.com/ + ├── bob@company.com/ + └── charlie@company.com/ +``` + +**Risk:** None - perfect isolation +**Verdict:** SAFE - Recommended for risk scanning + +--- + +### SECURE: Tenant-Scoped Cache ✅ + +``` +Load Balancer + | + +-- Goblet (tenant-scoped cache) + | + Cache Structure: + /cache/ + ├── tenant-org1/ + ├── tenant-org2/ + └── tenant-org3/ +``` + +**Risk:** Users within same tenant share cache (acceptable if intended) +**Verdict:** SAFE - Recommended for Terraform Cloud + +--- + +### SECURE: Sidecar Per Tenant ✅ + +``` +Tenant Org1 Namespace: + Pod-1: App + Goblet-Sidecar (cache-1) + Pod-2: App + Goblet-Sidecar (cache-2) + +Tenant Org2 Namespace: + Pod-3: App + Goblet-Sidecar (cache-3) + Pod-4: App + Goblet-Sidecar (cache-4) +``` + +**Risk:** None - network + storage isolation +**Verdict:** SAFE - Best for compliance-sensitive workloads + +--- + +## Security Checklist + +Before deploying Goblet in production with private repositories: + +- [ ] **Isolation Mode Configured**: Set `isolation_mode` appropriately +- [ ] **User/Tenant Identification**: Ensure claims extraction works +- [ ] **Authorization Tested**: Verify cross-tenant access blocked +- [ ] **File Permissions**: Ensure cache directories have restrictive permissions +- [ ] **Network Policies**: Implement if using Kubernetes +- [ ] **Audit Logging**: Enable access logs with user context +- [ ] **Encryption at Rest**: Consider for highly sensitive repos +- [ ] **Cache Eviction**: Implement for compliance (GDPR, retention) +- [ ] **Monitoring**: Alert on unauthorized access attempts +- [ ] **Documentation**: Document security model for users + +--- + +## Testing Isolation + +### Test User Isolation + +```bash +# User A fetches private repo +curl -H "Authorization: Bearer $TOKEN_USER_A" \ + http://goblet:8080/github.com/company/secrets/info/refs + +# Verify cached at /cache/user-a@company.com/... +ls /cache/user-a@company.com/github.com/company/secrets + +# User B attempts to access same repo +curl -H "Authorization: Bearer $TOKEN_USER_B" \ + http://goblet:8080/github.com/company/secrets/info/refs + +# Should either: +# 1. Return 403 Forbidden (if User B has no access) +# 2. Cache separately at /cache/user-b@company.com/... (if has access) + +# MUST NOT serve from User A's cache +ls /cache/user-b@company.com/ # Should be separate or empty +``` + +### Test Tenant Isolation + +```python +# Python test script +def test_tenant_isolation(): + # Tenant 1 fetches repo + headers_t1 = {"Authorization": f"Bearer {token_tenant1}"} + resp1 = requests.get(f"{goblet_url}/github.com/company/repo", headers=headers_t1) + assert resp1.status_code == 200 + + # Tenant 2 attempts access + headers_t2 = {"Authorization": f"Bearer {token_tenant2}"} + resp2 = requests.get(f"{goblet_url}/github.com/company/repo", headers=headers_t2) + + # Should fail if Tenant 2 has no access + assert resp2.status_code == 403 + + # Verify separate cache paths + assert os.path.exists("/cache/tenant-1/github.com/company/repo") + assert not os.path.exists("/cache/tenant-2/github.com/company/repo") +``` + +--- + +## Encryption at Rest (Future Enhancement) + +### Design + +```go +type EncryptedStorage struct { + backend Storage + keyManager KeyManager +} + +func (e *EncryptedStorage) Write(path string, data []byte) error { + encryptedData := e.keyManager.Encrypt(data) + return e.backend.Write(path, encryptedData) +} + +func (e *EncryptedStorage) Read(path string) ([]byte, error) { + encryptedData, err := e.backend.Read(path) + if err != nil { + return nil, err + } + return e.keyManager.Decrypt(encryptedData) +} +``` + +### Key Management Options + +1. **Local Key File**: Simple, for single-instance +2. **Environment Variable**: For containers +3. **KMS Integration**: AWS KMS, Google Cloud KMS, HashiCorp Vault +4. **Per-Tenant Keys**: Different key per tenant for isolation + +--- + +## Migration Guide + +### From Shared Cache to User-Scoped + +```bash +# 1. Stop Goblet +systemctl stop goblet + +# 2. Backup existing cache +mv /cache /cache.backup + +# 3. Update configuration +cat > /etc/goblet/config.yaml <