B BidWritePro

Security

Last Updated: May 8, 2026

BidWritePro is built for federal contractors, who operate under high standards of data protection, audit, and compliance. This page describes the technical and organizational security measures in place today, what we’re working on, and how to report security concerns.

Plain-English summary. Passwords are bcrypt-hashed. All traffic is HTTPS. Database is encrypted at rest. Each customer’s data is strictly isolated by user ID. Sessions are server-side and time-limited. File uploads are validated. Logins, password changes, and admin actions are audit-logged. Stripe handles all payment data — we never see card numbers. SOC 2 readiness is on the roadmap.

1. Authentication and sessions

Password storage In place

Passwords are hashed with bcrypt at a cost factor of 12. We never store passwords in plain text. Legacy SHA-256 hashes (from earlier versions) are silently upgraded to bcrypt the next time the user signs in.

Password complexity In place

New passwords must be at least 10 characters and contain a digit or symbol, or be at least 14 characters. The most common compromised passwords are blocked. Password resets follow the same rules.

Constant-time login In place

The login endpoint pays the same bcrypt cost on the user-not-found path as on a real user with a wrong password. This prevents timing-side-channel username enumeration.

Single-active-session policy In place

Each account permits one active session at a time. Signing in from a new device automatically invalidates any prior session, ensuring stolen tokens have a finite useful life.

Session storage In place

Session tokens are persisted server-side in PostgreSQL with a bounded TTL (currently 30 days). Logout invalidates the token immediately. Tokens are random 32-byte values generated with the operating system’s cryptographic entropy source.

Rate limiting In place

Authentication endpoints are rate-limited per IP address and per username:

  • Login: 10 attempts per IP per 5 minutes; 5 per username per 15 minutes
  • Password reset: 5 per IP per 15 minutes; 3 per username per hour
  • Registration: 5 per IP per 15 minutes
  • AI parse / proposal generation: 5 per user per 5 minutes (parse), 5 per user per hour (generate)

2. Encryption

Encryption in transit In place

All communication with the Service uses HTTPS with TLS 1.2 or higher. HTTP requests are redirected to HTTPS at the load balancer.

Database encryption at rest In place

Our PostgreSQL database is hosted on infrastructure that provides storage-layer encryption at rest using AES-256.

File storage encryption In place

Uploaded documents (RFPs, amendments, proposals, exports) are stored either in AWS S3 with server-side encryption (SSE-S3 or SSE-KMS), or, in fallback configurations, on the application’s host disk with the same storage-layer encryption as the database. S3 keys are scoped per user.

3. Multi-tenant data isolation

Per-user query scoping In place

Every database query that returns user data is scoped by the requesting user’s ID. Cross-user access is blocked at the application layer. Compliance matrices, proposals, saved solicitations, profiles, audit logs, and document records are all per-user.

S3 prefix scoping In place

When AWS S3 is the storage backend, every uploaded document is stored under a per-user prefix. Pre-signed URLs for download have a short TTL (5 minutes by default) and are issued only after the user is authenticated and the document is confirmed to belong to them.

Compliance matrix scoping In place

Compliance matrices generated from RFPs are stored both in the user’s proposal record (PostgreSQL) and, for short-term cache convenience, on disk with a filename prefix that includes the user ID. Cross-tenant access via the disk fallback was eliminated as part of pre-launch hardening.

4. File upload safety

Size and MIME validation In place

Uploaded files are subject to a 25 MB hard cap (covers every legitimate federal RFP we’ve tested against). Content-Length is checked before reading the body to prevent OOM attacks. MIME type and extension are both validated against an allowlist (PDF, DOCX, DOC, TXT). Rejection returns 413 (oversize) or 415 (wrong type).

Sandboxed text extraction In place

PDF and Word text extraction is performed by external command-line tools (pdftotext, pandoc) running in subprocess isolation. Uploaded files are written to disk under randomized UUID filenames; they are never executed.

5. Application security

SQL safety In place

All database access is via SQLAlchemy ORM with parameterized queries. Raw SQL is used only in two carefully-reviewed places (advisory locks for digest scheduling and the password-hash column-widening migration), both with bound parameters. No string-concatenated SQL.

Cross-site scripting (XSS) defenses In place

The frontend is React, which escapes user-supplied content by default. Outbound URLs from the API to <a href> are filtered through an allow-list of safe schemes (http/https/mailto/tel/relative); javascript: and data: schemes are blocked. Email digest content is HTML-escaped before assembly.

Cross-site request forgery (CSRF) In place

Authentication uses bearer tokens stored in the browser’s localStorage. Tokens are not sent automatically by the browser the way cookies are, removing the standard CSRF attack surface. Cross-origin requests are restricted by a tightened CORS policy: explicit method allowlist, explicit header allowlist, origin allowlist that includes only the production domain.

Prompt-injection mitigation In place

User-supplied document text is wrapped in delimited tags before being sent to the AI vendor, and the AI is given an explicit instruction to treat the document body as data, not as instructions. This reduces the surface for adversarial document content steering the AI.

Stack-trace redaction In place

Server errors return generic messages to the client. Real exception detail is logged server-side with type and message but never echoed in the API response, removing a class of information-disclosure leaks.

6. Audit logging

What we log In place

Every login, logout, password reset, registration, document upload, RFP parse, proposal generation, admin user action, and manual digest send is recorded in an audit log with timestamp, actor, target, and a short description. The audit log is accessible to admin users from the Admin Console.

What we don’t log In place

We do not log passwords, full session tokens, full document content, full prompts, or full AI responses. We do log the metadata that allows incident investigation (file size, parse outcome, request count) without the body content itself.

7. Payment security

Stripe handles all card data In place

Subscription billing is processed by Stripe, a PCI-DSS Level 1 service provider. Card numbers and CVVs are entered directly into Stripe’s secure form; they never touch our servers. We receive only a Stripe customer ID, subscription metadata, and (for receipts) the last four digits of the card.

Webhook signature verification In place

Stripe webhooks are verified using the signed-secret HMAC scheme. Unsigned, malformed, or replayed webhook events are rejected.

8. Default-credentials hardening

No hardcoded admin password In place

The administrator account is seeded only when the ADMIN_PASSWORD environment variable is set. If it is missing, the account seeder generates a one-time random password, prints it to the deploy log, and refuses to ship a guessable default. The site-gate password is similarly env-driven, with no fallback.

9. Sub-processors and infrastructure

BidWritePro relies on a small number of carefully-selected vendors. See our Privacy Policy for the full list. Highlights:

  • Stripe — payments (PCI-DSS Level 1)
  • Anthropic — AI features. Per Anthropic’s API terms, customer data is not used to train Anthropic’s models
  • Railway — application and database hosting (U.S.)
  • AWS S3 — encrypted document storage (when configured)
  • Resend / Brevo — transactional email delivery
  • SAM.gov — U.S. General Services Administration opportunity feed

10. Compliance posture

SOC 2 Type II In progress

SOC 2 Type II audit readiness is on our 2026 roadmap. The technical practices on this page were designed with SOC 2 control objectives in mind. We will publish the report and an executive summary when available.

FedRAMP / IL2 / IL4 Not authorized

BidWritePro is hosted on commercial cloud infrastructure that is not FedRAMP-authorized for the storage or processing of classified information, Controlled Unclassified Information (CUI), or other restricted federal data categories. Do not upload material in those categories. See the corresponding clause in our Terms of Service.

U.S. data residency In place

All BidWritePro infrastructure (application servers, PostgreSQL, S3 storage) is hosted in the United States. We do not currently support EU/UK data residency.

11. Vulnerability disclosure

If you believe you’ve found a security vulnerability in BidWritePro, please report it responsibly to [email protected] with the subject line “Security Disclosure”. Include:

  • A description of the issue and its potential impact
  • Steps to reproduce
  • Any proof-of-concept material you can share safely
  • Whether you wish to be credited publicly when the issue is resolved

We commit to:

  • Acknowledge receipt within 2 business days
  • Provide a substantive update within 10 business days
  • Take no legal action against good-faith researchers who follow this process
  • Credit you publicly (with your permission) when the issue is fixed

Please do not test for vulnerabilities against accounts other than your own, and please do not access, modify, or exfiltrate data belonging to other users in the course of any test.

12. Incident response

If a security incident affects your data, we will notify affected users by email at the address on file as soon as we have a substantiated, accurate understanding of the incident. Notifications will include the nature of the incident, the data affected, the steps we’ve taken in response, and the steps you should take. We follow applicable U.S. state breach-notification timelines, which generally require notification within 30 to 60 days of confirmation, depending on the state.

13. Contact

For security questions, vulnerability reports, or audit/compliance documentation requests:

Cortexis Group, LLC
Attn: Security
13611 South Dixie Highway, Suite 453
Miami, Florida 33176
United States
Email: [email protected]

Home Privacy Terms Security Contact
© 2026 Cortexis Group, LLC  ·  BidWritePro is a service of Cortexis Group, LLC, a Florida limited liability company.