How we protect your data
Every control we run — encryption, access, audit, incident response — documented in the order we would want to read them.
AES-256-GCM at rest. TLS 1.3 in transit.
DynamoDB, S3, SQS, CloudWatch Logs — every data store.
AWS Cognito with short-lived JWTs.
Passwords never touch our code. Secure-store on device.
Secrets Manager and Parameter Store.
No long-lived IAM keys; GitHub Actions uses OIDC.
pip-audit and bandit on every PR.
Build fails on any known CVE in runtime dependencies.
30-min on-call response, 24/7.
Breach notification within 72 hours per GDPR Art. 33/34.
Type I target Q3 2026.
In-progress via Vanta continuous monitoring.
Encryption
At rest
All user data is encrypted at rest using AES-256-GCM:
- DynamoDB: AWS-managed SSE (AES-256). Table-level encryption with AWS-owned KMS keys (migration to customer-managed CMKs is on the SOC 2 roadmap).
- S3 (résumé files): SSE-S3 (AES-256). Bucket ACLs are fully private; presigned URLs (15-minute TTL) are the only access path.
- SQS queues: Server-side encryption enabled on all job-application queues.
- CloudWatch Logs: Encrypted with the default AWS-managed KMS key.
In transit
- CloudFront + API Gateway: TLS 1.3 enforced. TLS 1.0 and 1.1 explicitly disabled on all distributions. Security policy:
TLSv1.2_2021minimum, preferred ciphers only. - Mobile app → API: Certificate pinning on production builds via Expo's
expo-modules-corenetwork layer. Pinned to the CloudFront certificate chain. - Internal Lambda → AWS services: All AWS SDK calls use HTTPS by default; explicit
use_ssl=Truein boto3 session config. - LLM provider calls: HTTPS only. No request bodies are logged to CloudWatch (only provider name, method, duration, and status code per Jobeezy logging policy).
LLM zero-retention contracts
Both Anthropic (primary) and OpenAI (fallback) are under contractual zero-data-retention agreements. Résumé text and job descriptions sent for tailoring are not stored on provider infrastructure and are never used to train or fine-tune any model. Confirmed via provider enterprise DPA.
Authentication and access control
User authentication
- Provider: AWS Cognito User Pools (us-east-1).
- Tokens: JWT access tokens (15-min TTL) + refresh tokens (30-day TTL). Stored in device Keychain (iOS) / Keystore (Android) via
expo-secure-store— never in AsyncStorage. - Passwords: 12+ characters, complexity rules enforced by Cognito (uppercase + lowercase + digit + symbol). bcrypt hashing managed by Cognito (user passwords never touch Jobeezy application code).
- MFA: TOTP-based MFA is available and can be enrolled by users in settings. Not enforced for all accounts; required for admin access.
IAM and least privilege
- Every Lambda function has its own IAM execution role with the minimum permissions needed for that function. No shared roles across functions.
- No wildcard
*resource policies in any IAM role or policy. All DynamoDB and S3 permissions are scoped to specific table/bucket ARNs. - API keys and secrets are managed via AWS Secrets Manager and Parameter Store — never stored in code, environment variables, or committed to git.
- CI/CD: GitHub Actions uses OIDC with short-lived role assumption (no long-lived IAM keys in secrets).
Rate limiting and abuse protection
- AWS WAF: 4 managed rule groups active on all CloudFront distributions (CRS, KnownBadInputs, IpReputation, BotControl).
- API rate limit: 2,000 requests per 5 minutes per IP for
/api/*paths. Returns HTTP 429 withRetry-After: 300. - Per-Lambda instance rate limiting on auth endpoints (additional safeguard; full distributed rate limiting is on the roadmap).
- Known scanner paths (
/wp-admin,/.env,/.git, etc.) blocked at WAF with HTTP 403.
Infrastructure hardening
Serverless attack surface reduction
- No always-on EC2 instances or containers — Lambda functions eliminate entire classes of vulnerability (no OS patching, no persistent network exposure).
- Lambda runtimes are pinned to Python 3.12 and updated in CI on each dependency audit (
pip-auditruns on every PR). - No SSH access to any compute. All operational changes go through CloudFormation/SAM deployments.
- VPC isolation is not currently implemented (Lambda runs in the AWS-managed VPC with private access to AWS services via VPC endpoints — on the SOC 2 roadmap to add customer VPC).
Dependency security
- CI pipeline runs
pip-auditon every PR — fails the build on any known CVE in runtime dependencies. banditstatic analysis on all Python code — catches common security anti-patterns (hardcoded secrets, shell injection, etc.).rufflinter enforces no-bare-except rules, preventing silent error swallowing.- Dependency addition policy: any new package must pass last-commit-date, weekly-download, license (MIT/Apache/BSD), bundle-size, and CVE checks before merging.
S3 security configuration
- All S3 buckets have
BlockPublicAcls: true,BlockPublicPolicy: true,IgnorePublicAcls: true,RestrictPublicBuckets: trueexcept the CloudFront origin bucket (which uses OAC, not public access). - S3 Object Lock is not currently enabled (on SOC 2 roadmap for audit log buckets).
- Server-side encryption using SSE-S3 on all buckets. SSE-KMS upgrade on SOC 2 roadmap.
Audit logging
- All Lambda invocations emit structured JSON logs via
structlogto CloudWatch Logs. Log format:{"level", "timestamp", "event", "actor_id", "resource", "duration_ms", "status"}. - No PII (names, emails, résumé content) is written to logs. Log scrubbing rules are enforced by policy and reviewed in code review.
- DynamoDB mutations include
actor_idandupdated_aton every write — sufficient to reconstruct an audit trail for any record. - CloudTrail is enabled on the AWS account for all management API calls (IAM changes, S3 bucket policy changes, etc.) with 90-day retention.
- CloudWatch log groups have 90-day retention; WAF logs are retained for 90 days in S3.
- Sentry captures all unhandled exceptions with PII scrubbing rules (email patterns, phone patterns, résumé keywords excluded from event payloads).
Monitoring and incident response
| Tool | What it monitors | Alert on |
|---|---|---|
| CloudWatch Synthetics | API health, site availability, job search pipeline | HTTP status ≠ 200, latency > 3s, JSON schema mismatch |
| CloudWatch Alarms | Lambda error rate, DynamoDB throttles, SQS queue depth | Error rate > 1%, throttle events > 10/min |
| AWS WAF Metrics | Blocked requests by rule, rate-limit triggers | Block rate spike > 500% baseline |
| Sentry | Mobile app and backend crash/error rate | New error type or error rate spike |
| CloudWatch RUM | Real-user page load, JavaScript errors, Web Vitals | LCP > 4s, CLS > 0.25, error rate spike |
Incident response
- Detection: Automated CloudWatch alarms → SNS →
status_updaterLambda updates status.jobeezy.com automatically. - Response time: Critical issues (data breach, service outage) — on-call response within 30 minutes 24/7.
- Breach notification: Users and affected parties notified within 72 hours of confirmed breach per GDPR Art. 33/34 and applicable state laws.
- Status transparency: All incidents posted to status.jobeezy.com within 15 minutes of confirmation, with hourly updates until resolved.
Responsible disclosure program
Scope
- In scope: jobeezy.com, api.jobeezy.com, the Jobeezy iOS and Android apps, any subdomain of jobeezy.com.
- Out of scope: Third-party services (AWS infrastructure, Cognito, Anthropic), denial-of-service attacks, social engineering of employees, physical attacks.
What we ask
- Report via email to security@jobeezy.com or via our security.txt.
- Include: affected URL/endpoint, description of the vulnerability, steps to reproduce, and potential impact.
- Allow us reasonable time to fix before public disclosure (we target 90 days for non-critical, 7 days for critical).
- Do not access, modify, or delete user data beyond what is necessary to demonstrate the vulnerability.
What we commit to
- Acknowledge your report within 72 hours.
- Provide regular status updates as we investigate and fix.
- Credit you (by name or handle) in our security disclosure if you wish.
- Not pursue legal action against researchers acting in good faith under this policy.
Our security.txt is published at /.well-known/security.txt per RFC 9116 and is kept up to date with current contact info and expiry date.
SOC 2 readiness
We are working toward SOC 2 Type I certification (target Q3 2026), using Vanta for continuous control monitoring. Trust Service Criteria in scope: Security, Availability, and Confidentiality.
| Control | Status |
|---|---|
| Encryption at rest (AES-256) | Implemented |
| Encryption in transit (TLS 1.3) | Implemented |
| Access control + IAM least privilege | Implemented |
| Vulnerability scanning (pip-audit + bandit) | Implemented in CI |
| Audit logging (CloudTrail + structured logs) | Implemented |
| Incident response plan | Documented |
| Customer-managed KMS keys (CMK) | In progress |
| Formal penetration test | Scheduled Q2 2026 |
| SOC 2 Type I audit | Target Q3 2026 |
| Employee security awareness training | In progress |