Security practices

How we protect your data

Every control we run — encryption, access, audit, incident response — documented in the order we would want to read them.

Encryption

AES-256-GCM at rest. TLS 1.3 in transit.

DynamoDB, S3, SQS, CloudWatch Logs — every data store.

Auth

AWS Cognito with short-lived JWTs.

Passwords never touch our code. Secure-store on device.

Secrets

Secrets Manager and Parameter Store.

No long-lived IAM keys; GitHub Actions uses OIDC.

Dependencies

pip-audit and bandit on every PR.

Build fails on any known CVE in runtime dependencies.

Incident response

30-min on-call response, 24/7.

Breach notification within 72 hours per GDPR Art. 33/34.

SOC 2

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_2021 minimum, preferred ciphers only.
  • Mobile app → API: Certificate pinning on production builds via Expo's expo-modules-core network layer. Pinned to the CloudFront certificate chain.
  • Internal Lambda → AWS services: All AWS SDK calls use HTTPS by default; explicit use_ssl=True in 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 with Retry-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-audit runs 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-audit on every PR — fails the build on any known CVE in runtime dependencies.
  • bandit static analysis on all Python code — catches common security anti-patterns (hardcoded secrets, shell injection, etc.).
  • ruff linter 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: true except 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 structlog to 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_id and updated_at on 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

ToolWhat it monitorsAlert 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_updater Lambda 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.

Report a vulnerability

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.

ControlStatus
Encryption at rest (AES-256)Implemented
Encryption in transit (TLS 1.3)Implemented
Access control + IAM least privilegeImplemented
Vulnerability scanning (pip-audit + bandit)Implemented in CI
Audit logging (CloudTrail + structured logs)Implemented
Incident response planDocumented
Customer-managed KMS keys (CMK)In progress
Formal penetration testScheduled Q2 2026
SOC 2 Type I auditTarget Q3 2026
Employee security awareness trainingIn progress