Skip to main content

Security & Privacy

Grove is built with security and privacy as fundamental requirements, not afterthoughts. This document outlines our security architecture, data protection measures, and privacy controls.

Security Philosophy


Security Architecture

Defense in Depth

Grove implements multiple security layers to protect user data:

Security Controls Matrix

LayerControlImplementationStatus
TransportTLS 1.3Supabase managedActive
TransportHSTSSupabase defaultActive
AuthJWT tokensSupabase AuthActive
AuthOAuth 2.0Google, AppleActive
AuthPassword hashingbcryptActive
AuthzRow Level SecurityPostgreSQL RLSActive
AuthzRole-based accessOwner/Admin/MemberActive
DataEncryption at restSupabase managedActive
DataSigned URLsStorage accessActive
MonitoringAudit logsPlannedPlanned

Authentication Security

Authentication Flow

Token Security

Token Types:

TokenLifetimeStorageRefresh
Access Token1 hourMemoryAuto-refresh
Refresh Token7 daysSecure StorageOn expiry

Secure Storage Implementation:

// iOS: Keychain
// Android: EncryptedSharedPreferences
import * as SecureStore from 'expo-secure-store';

await SecureStore.setItemAsync('refresh_token', token, {
keychainAccessible: SecureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY,
});

Password Requirements

  • Minimum 8 characters
  • No maximum limit
  • Hashed with bcrypt (cost factor 10)
  • No password stored in plaintext

OAuth Security (PKCE)


Authorization Security

Row Level Security (RLS)

Every table in Grove has RLS policies that enforce access control at the database level:

Example RLS Policies:

-- Users can only view communities they belong to
CREATE POLICY "community_member_select"
ON communities FOR SELECT
USING (
id IN (
SELECT community_id FROM community_members
WHERE user_id = auth.uid()
)
);

-- Only community owners can delete communities
CREATE POLICY "community_owner_delete"
ON communities FOR DELETE
USING (
id IN (
SELECT community_id FROM community_members
WHERE user_id = auth.uid() AND role = 'owner'
)
);

-- Users can only update their own profile
CREATE POLICY "profile_owner_update"
ON profiles FOR UPDATE
USING (id = auth.uid());

Role-Based Access Control

Permission Matrix:

ActionOwnerAdminMember
Delete communityYesNoNo
Transfer ownershipYesNoNo
Manage membersYesYesNo
Change settingsYesYesNo
Create eventsYesYesNo
Create postsYesYesYes
Send messagesYesYesYes
View contentYesYesYes
RSVP to eventsYesYesYes

Data Protection

Encryption

In Transit:

  • All API calls over HTTPS (TLS 1.3)
  • WebSocket connections use WSS
  • No sensitive data in query parameters

At Rest:

  • Database encryption managed by Supabase
  • Storage buckets encrypted
  • Backups encrypted

Sensitive Data Handling

Media Security

Storage Access Control:

Signed URL Implementation:

// Generate signed URL with expiration
const { data } = supabase.storage
.from('community-images')
.createSignedUrl(path, 3600); // 1 hour expiry

Privacy Controls

Data Minimization

Grove only collects data necessary for the service:

Data TypePurposeRetention
EmailAuthentication, notificationsAccount lifetime
NameDisplay in communityAccount lifetime
AvatarProfile displayAccount lifetime
MessagesCommunity communicationIndefinite
TransactionsFinance tracking7 years (compliance)

User Privacy Rights

Privacy Features

  1. Profile Visibility

    • Profile visible only to community members
    • Can hide email from other members
    • No public profile pages (MVP)
  2. Data Access

    • Users can view all their data
    • Export functionality planned
    • Account deletion available
  3. Communication Preferences

    • Push notification controls
    • Email notification preferences
    • Per-community notification settings

Compliance

GDPR Readiness

RequirementStatusImplementation
Lawful basisReadyConsent + Legitimate interest
Data minimizationReadyOnly necessary data collected
Purpose limitationReadyClear purposes documented
Right to accessReadyProfile view in app
Right to rectificationReadyEdit profile in app
Right to erasureReadyAccount deletion
Data portabilityPlannedExport feature
Privacy by designReadyBuilt into architecture

Data Processing

Third-Party Processors:

ProcessorPurposeData SharedDPA
SupabaseBackend infrastructureAll user dataYes
Google CloudOAuth, infrastructureAuth dataYes
AppleApple Sign-InAuth dataYes
ExpoPush notificationsPush tokensYes

Threat Model

Identified Threats

Security Controls by Threat

ThreatRiskMitigationStatus
SQL InjectionHighParameterized queries via SupabaseMitigated
XSSMediumReact Native (no DOM)N/A
CSRFMediumSameSite cookies, token authMitigated
Auth bypassHighRLS, JWT validationMitigated
Data exposureHighRLS policies, scoped accessMitigated
Brute forceMediumRate limiting, lockoutPartial
Token theftMediumSecure storage, short expiryMitigated

Security Monitoring

Current Monitoring

  • Supabase Dashboard: API usage, errors
  • Authentication logs: Sign-in attempts
  • Storage logs: Access patterns

Planned Monitoring

Security Events to Monitor

EventSeverityAction
Multiple failed loginsHighTemporary lockout
Unusual API patternsMediumReview and alert
RLS policy violationsHighLog and investigate
Token refresh failuresLowMonitor trends
Mass data accessHighAlert immediately

Incident Response

Response Plan

Severity Levels

LevelDefinitionResponse Time
CriticalActive data breachImmediate
HighSecurity vulnerability4 hours
MediumPotential exposure24 hours
LowMinor issue1 week

Security Checklist

Pre-Launch Security

  • TLS enabled on all endpoints
  • JWT token validation
  • RLS policies on all tables
  • Password hashing with bcrypt
  • OAuth with PKCE
  • Secure token storage
  • Input validation
  • Rate limiting configured
  • Audit logging enabled
  • Security monitoring setup
  • Incident response plan tested

Ongoing Security

  • Quarterly security review
  • Dependency vulnerability scanning
  • Penetration testing (annual)
  • Security training for team
  • Privacy policy updates