docs: consolidate repository guides and preserve audit history

This commit is contained in:
cesnimda
2026-09-11 14:22:41 +02:00
parent 115441a409
commit 682a3028bb
404 changed files with 3402 additions and 2621 deletions
+11
View File
@@ -0,0 +1,11 @@
# Security
Security is enforced in the API and deployment topology, not by UI visibility. The current baseline includes tenant owner filters, local/Google/Microsoft identity options, cookie CSRF protection, rate limits, TOTP, session revocation, validated uploads/imports, bounded document parsing, private AI networking, and structured error handling.
- [Authentication](authentication.md)
- [Authorization and tenancy](authorization.md)
- [Sessions and rate limits](sessions.md)
- [File and import security](file-security.md)
- [Current findings and verification limits](security-notes.md)
Historical audits remain recoverable in [`../_archive/`](../_archive/); only verified current claims belong here.
-35
View File
@@ -1,35 +0,0 @@
# AI Security
## Purpose
Protect against AI-related risks.
---
# Prompt Injection
Untrusted content:
- Job descriptions.
- Uploaded CVs.
- Emails.
must not control AI behaviour.
---
# AI Output Validation
Check:
- Unsupported claims.
- Dangerous content.
- Formatting issues.
---
# Data Handling
Only send required information.
Avoid unnecessary exposure.
-40
View File
@@ -1,40 +0,0 @@
# API Security
## Requirements
All APIs must:
- Authenticate correctly.
- Validate input.
- Return safe errors.
---
# Rate Limiting
Protect:
- Login.
- AI endpoints.
- File uploads.
- Public CV pages.
---
# API Keys
Admin-only.
Never expose:
- Provider keys.
- Secrets.
- Tokens.
---
# External APIs
Validate responses.
Do not trust third-party data.
+2 -81
View File
@@ -1,84 +1,5 @@
# Authentication
## Purpose
Local email/password accounts issue signed local JWTs and can use an HttpOnly `jobtracker_auth` session cookie. Google and Microsoft identity sign-in are optional and configured separately from Gmail/Graph mail access. Registration is disabled by default; email verification, Turnstile, and production auth requirements are configuration gates.
Define user login and registration.
---
# Supported Methods
Users should be able to:
## Email Registration
Create account using:
- Email.
- Password.
- Confirmation.
---
## OAuth Registration/Login
Support:
- Google.
- Microsoft.
---
# Expected Behaviour
If OAuth user does not exist:
Create account automatically.
Example:
User clicks:
"Continue with Google"
↓
Authenticate
↓
No account exists
↓
Create account
↓
Login
---
# Password Requirements
Support:
- Secure hashing.
- Password reset.
- Password change.
---
# Authentication UX
Users should have:
- Clear errors.
- Loading states.
- Recovery options.
Avoid:
"Authentication failed"
without explanation.
Password reset and verification use SMTP. TOTP two-factor authentication includes encrypted secrets, recovery codes, trusted devices, and pending-token flow. JWT issuer, audience, key, lifetime, and external client IDs are documented in [environment variables](../configuration/environment-variables.md).
+3 -41
View File
@@ -1,43 +1,5 @@
# Authorization
# Authorization and tenancy
## Purpose
Tenant-owned records carry `OwnerUserId` directly or through a parent. `JobTrackerContext` applies global owner filters with deny-on-null semantics; services and background work use explicit owner checks when they bypass request-scoped filters. Admin users access user management, audit, and system readiness surfaces through Identity roles.
Control access to resources.
---
# User Isolation
A user must only access:
- Their jobs.
- Their CV.
- Their files.
- Their emails.
- Their settings.
---
# Admin Role
Admins may access:
- System settings.
- Provider configuration.
- Monitoring.
---
# API Rules
Every protected endpoint must verify:
1. User identity.
2. User permission.
3. Resource ownership.
---
# Never Trust Frontend
The backend must enforce permissions.
A browser route or hidden control is not an authorization boundary. Add server-side authorization and an ownership regression test for every new resource or endpoint.
+3 -54
View File
@@ -1,56 +1,5 @@
# File Security
# File and import security
## Purpose
Attachment uploads use a managed data root, validated metadata, size/type/signature checks, and safe download paths. Parser decoding is isolated and resource-bounded. URL import validates destinations and rejects unsafe redirects; DNS rebinding and actual socket binding remain a documented verification concern.
Protect uploaded documents.
---
# File Types
Potential uploads:
- PDF.
- DOCX.
- Images.
- Portfolio files.
---
# Validation
Check:
- File type.
- File size.
- File contents.
Never trust extensions.
---
# Processing
Uploaded files may contain:
- Malicious content.
- Embedded scripts.
- AI prompt injection.
Treat as untrusted.
---
# Storage
Requirements:
- Secure naming.
- Access control.
- User ownership checks.
---
# PDF Processing
Never directly trust extracted text.
Generated CV previews are sandboxed and public CV/PDF links are random, revocable, noindex, and rate-limited. Never log or document private file contents, connection strings, or bearer tokens.
-48
View File
@@ -1,48 +0,0 @@
# Input Validation
## Purpose
Protect the application.
---
# Validate
All inputs:
- Forms.
- APIs.
- Imports.
- Files.
- AI outputs.
---
# Protection Against
Examples:
- SQL injection.
- XSS.
- HTML injection.
- Malicious uploads.
---
# CV Builder
Special attention:
Users can create:
- Custom sections.
- HTML-like content.
- Formatting.
The renderer must sanitise content.
---
# Rule
Never render user content directly without validation.
-64
View File
@@ -1,64 +0,0 @@
# Security Overview
## Purpose
Define security requirements for Jobjakt.
The application stores sensitive career information including:
- CVs.
- Employment history.
- Personal details.
- Job applications.
- Documents.
- Communication.
Security must be considered a core product requirement.
---
# Security Goals
Jobjakt should provide:
- Secure authentication.
- Strong user separation.
- Safe document handling.
- Protected APIs.
- Secure AI integrations.
---
# Security Principles
## Least Privilege
Users should only access their own data.
Admins have additional permissions.
---
## Secure By Default
Features should default to safe behaviour.
---
## Validate Everything
All external input should be considered untrusted.
Sources:
- Forms.
- APIs.
- Uploaded files.
- AI responses.
- Imported job descriptions.
---
## Do Not Over-Engineer
Security should protect users without harming usability.
-51
View File
@@ -1,51 +0,0 @@
# Privacy
## Principles
Users own their information.
---
# Requirements
Support:
- Data deletion.
- Export.
- Consent.
---
# Public CV
Users choose:
Enabled.
Disabled.
---
# Public URLs
Use:
Random UUID.
Example:
/cv/8a92f3e2-xxxx
Avoid:
Predictable usernames.
---
# Future SaaS
Consider:
- Privacy policy.
- GDPR compliance.
- Data processing agreements.
-51
View File
@@ -1,51 +0,0 @@
# SaaS Security
## Future Requirements
When moving to SaaS:
Support:
- Multiple users.
- Subscription plans.
- Usage limits.
---
# Tenant Isolation
Every resource belongs to:
User
or
Organisation.
---
# Billing Security
Never trust client-side:
- Subscription status.
- Permissions.
- Limits.
Verify server-side.
---
# Admin Features
Protect:
- User management.
- AI providers.
- System settings.
---
# Principle
Prepare architecture without adding unnecessary complexity early.
+16
View File
@@ -0,0 +1,16 @@
# Current security notes
## Verified locally
- Tenant isolation, authorization replay, session revocation, upload/parser boundaries, AI sidecar token checks, PDF admission, and high-severity dependency gates have focused regression coverage.
- The AI service is not published to the host in the production Compose topology; only the backend joins its private network.
- Production Compose requires an AI service token and enables backend authentication by default.
## Requires external or manual verification
- Trusted proxy/ingress CIDRs, host firewall closure, TLS/redirect behavior, and production network topology.
- Authenticated production smoke tests, real OAuth/provider behavior, email delivery, backup/restore, rollback, and key custody.
- Full keyboard/screen-reader/zoom review of the CV builder and complete production UI console cleanliness.
- Account-deletion retention policy, tombstone protection, and restored-backup erasure behavior.
These are not claims of resolved security findings. Dated evidence and the detailed P1/P2 audit packet are archived under `docs/_archive/pre-docs-cleanup-2026-09-11/docs/audits/` and the pre-existing archive.
+5
View File
@@ -0,0 +1,5 @@
# Sessions and rate limits
Session cookies are HttpOnly and SameSite=Lax, with Secure behavior controlled by deployment. Mutating cookie-authenticated requests use a CSRF double-submit cookie/header check. Users can list and revoke sessions; logout clears local client state.
Dedicated fixed-window limits cover login, authentication email, two-factor challenges, and anonymous public-CV PDF export. AI usage is bounded by account/monthly generation and token policy. Rate limits are a security and capacity control; do not loosen them to mask provider or UI failures.
-40
View File
@@ -1,40 +0,0 @@
# Supply-chain and credential scanning policy
## Required repository gates
Pull requests and `main` builds must pass all of the following without silently excluding a project:
- locked NuGet restore for the API and test project;
- `npm ci` plus the configured high-severity audit gate;
- hash-required installation of the Linux Python lock;
- the package-manager advisory checks recorded in CI;
- `python3 scripts/supply-chain.py scan-secrets` over every Git-tracked file; and
- `python3 scripts/supply-chain.py generate-sbom --output .artifacts/jobjakt.cdx.json`.
The generated CycloneDX 1.5 SBOM combines the committed npm, NuGet and Python lock files. It is a build artifact, not a replacement for the locks or an image scan. Its lock digest and deterministic component ordering make dependency changes reviewable without adding generated files to source control.
The built-in tracked-secret scanner is deliberately high confidence. It detects private-key headers and recognizable JWT, AWS, GitHub, Google, Slack and live Stripe credentials, skips binary files and files over 2 MiB, and reports only the credential class and file location. It never prints a matched value. This gate complements—not replaces—host secret management, history review and a dedicated scanner when one is approved.
## Dependency and advisory exceptions
High or critical reachable advisories block release. An exception must be a reviewed repository document containing the package and affected path, advisory identifiers, reachability evidence, compensating control, accountable owner, expiry date and removal condition. Expired or ownerless exceptions fail closed. A version pin alone is not an exception.
The outstanding Torch/Transformers findings are not accepted exceptions. Their model-loading path and production image remain blocked pending a compatible resolution or a bounded, reviewed isolation decision.
## Immutable inputs
Third-party workflow actions, container bases and downloaded installers must move only to identifiers verified from their authoritative upstream source. Do not guess a commit SHA, image digest or installer checksum. Updates are reviewed commits and retain the prior known-good identifier for rollback.
The current mutable action/image references and `dotnet-install.sh` download remain open until network-backed upstream metadata and a container scanner are available. The local SBOM and tracked-secret gates do not claim to close those items.
## Credential response
If the tracked scan or a reviewer finds a real credential:
1. stop the affected build and suppress the value from chat, tickets and logs;
2. revoke or rotate it at the issuing system before treating source cleanup as sufficient;
3. remove it from the current tree and add the narrow prevention rule or ignore boundary needed;
4. assess reachable history and CI artifacts using filenames/commit IDs only; and
5. coordinate any history rewrite separately because it disrupts clones and does not revoke a credential.
Never weaken a detector merely to make an unexplained finding pass.
@@ -1,82 +0,0 @@
# Two Factor Authentication
## Purpose
Provide additional account protection.
---
# Preferred Method
TOTP authentication.
Compatible with:
- Google Authenticator.
- Microsoft Authenticator.
- Authy.
---
# Flow
Enable 2FA:
User requests setup
↓
Generate secret
↓
Display QR code
↓
User scans
↓
User confirms code
↓
Enable 2FA
---
# Login Flow
Password/OAuth
↓
Request authenticator code
↓
Validate
↓
Login
---
# Recovery
Support:
- Backup codes.
- Disable/reset through account recovery.
---
# UX Requirements
Explain clearly:
- Why enable 2FA.
- How it works.
- Recovery options.
-8
View File
@@ -1,8 +0,0 @@
# uploads
Uploads are tenant-scoped through their parent application. File names are normalized with
`Path.GetFileName` and stored under generated names inside the configured attachments root. The API
enforces allowed types, a per-file size limit, and the account's total storage entitlement.
Downloads resolve the owned database record before opening a file. Files selected for AI are explicit;
uploading alone does not send content to a provider.
-48
View File
@@ -1,48 +0,0 @@
# User Data Protection
## Purpose
Protect personal career information.
---
# Stored Data
Potential sensitive information:
- CV content.
- Employment history.
- Contact information.
- Documents.
- Email communication.
---
# Requirements
Support:
- User export.
- User deletion.
- Data ownership.
---
# Database
Ensure:
- Correct relationships.
- No cross-user queries.
- Safe migrations.
---
# Logging
Never log:
- Passwords.
- Tokens.
- Private documents.
- Sensitive CV content.
-8
View File
@@ -1,8 +0,0 @@
# validation
Validation happens at trust boundaries: controller request DTOs, file uploads, imported URLs, OAuth
state callbacks, AI sidecar authentication, and deployment configuration. Job import and IMAP targets
resolve through SSRF guards that reject private, loopback, link-local, and unsafe redirect targets.
Unhandled failures use Problem Details with a trace ID; expected validation failures retain their
specific 4xx responses. See `docs/security/input-validation.md` and `docs/security/api-security.md`.