Security Principles
Four principles guide every security decision in the system. They are not aspirational. They are enforced in code and verified by tests.
| Principle | Implementation |
|---|---|
| Defense in depth | Multiple layers of security from input to output. Input validation, authentication, rate limiting, output sanitization, and container isolation all operate independently. |
| Least privilege | Docker non-root user (UID 1000). Kubernetes securityContext with runAsNonRoot. API key auth with minimum required scope per endpoint group. |
| Fail safe | Security checks default to blocking on error, not allowing. If the SecurityEngine throws, the request is rejected. If auth fails to resolve, access is denied. |
| Auditable | All security decisions are logged. All API calls require authentication. No endpoint is anonymous by default. |
Authentication
API key authentication is the single entry point for every protected endpoint. Keys are never stored in plaintext.
- Header:
X-API-Keyon every request to a protected endpoint - Storage: SQLite user database with bcrypt hashing. The raw key never touches disk after issuance.
- Comparison: Constant-time comparison via
secrets.compare_digest()to prevent timing attacks that could leak key material byte by byte - Enforcement: All protected endpoints require a valid API key. No exceptions, no bypass paths.
- Admin endpoints: Router-level dependency injection enforces auth before the handler runs. The check happens once, at the framework layer, not inside each route function.
# Auth flow
1. Extract X-API-Key header
2. Look up user record in SQLite
3. bcrypt.verify(provided_key, stored_hash)
4. secrets.compare_digest on resolved key
5. Attach user context to request
6. Reject with 401 if any step fails
Rate Limiting
The slowapi library throttles requests at the application layer. Two tiers of limits apply depending on endpoint cost.
| Scope | Limit | Rationale |
|---|---|---|
| Global (all endpoints) | 100 requests / minute | Default ceiling for any authenticated client |
| /process endpoint | 30 requests / minute | Stricter limit on compute-heavy cognitive pipeline invocations |
When a client exceeds the limit, the API returns 429 Too Many Requests with a Retry-After header indicating how many seconds to wait. Both limits are configurable via environment variables, so operators can tune them for their deployment without code changes.
CORS
Cross-origin requests are controlled at the framework layer. Nothing is open by default.
- Allowed origins: Configurable via the
CORS_ALLOWED_ORIGINSenvironment variable. No wildcard in production. - Methods: GET, POST, PUT, DELETE. PUT and DELETE are enabled for admin API operations such as key rotation and configuration updates.
- Credentials: Support for authenticated cross-origin requests. Browsers send the API key header with proper preflight handling.
- Preflight caching: Enabled to reduce OPTIONS round-trips. Browsers cache the preflight response for the configured max age.
Input Security
File: SecurityEngine.check_input()
Every user input passes through the SecurityEngine before it reaches the cognitive pipeline. The engine runs pattern-based detection across five threat categories.
| Threat Category | Detected Patterns |
|---|---|
| Prompt injection | "ignore previous instructions", "you are now", "system prompt", and similar override attempts |
| SQL injection | Union-based, boolean-based, and time-based injection patterns |
| XSS | Script tag injection, event handler attributes, javascript: URIs |
| Path traversal | ../ sequences, absolute path escapes, encoded traversal variants |
| Command injection | Shell metacharacters, command chaining, subshell invocation patterns |
All detected threats are logged with the matched pattern and the raw input hash. The request is blocked. No partial processing occurs.
Output Security
File: SecurityEngine.check_output()
Output security operates on a different threat model than input security. The system checks generated output before it reaches the client. This runs as Stage 12 in the 18-stage pipeline.
| Check | What It Catches |
|---|---|
| PII detection | Email addresses, phone numbers, credit card numbers (pattern-matched, not heuristic) |
| Secret leakage | API keys, bearer tokens, passwords, and other credential patterns in generated text |
| Prompt injection echo | Checks whether an input injection attempt is reflected in the output, which would indicate the pipeline was subverted |
Input and output security are separate by design. A clean input does not guarantee a clean output. Both must pass independently.
Docker Security
The container image is built to minimize attack surface. Build tools and development dependencies never reach the runtime image.
- Multi-stage build: First stage installs build dependencies and compiles assets. Second stage copies only the runtime artifact. The final image contains no compilers, no build tools, no test fixtures.
- Non-root user: The application runs as
novaspire(UID 1000). If an attacker escapes the application process, they land in a non-root account with no sudo access. - No package installation in runtime: The runtime image has no package manager cache.
aptandpipcaches are stripped. No runtime dependency installation is possible. - Minimal base image:
python:3.11-slim. Smaller surface area than full Debian-based images. Fewer packages means fewer CVEs. - Health check: Container exposes a health endpoint for orchestration platforms to detect and restart unhealthy instances.
Kubernetes Security
Pod-level security controls enforce isolation and resource boundaries in production deployments.
| Control | Configuration |
|---|---|
| securityContext | runAsNonRoot: true, runAsUser: 1000, readOnlyRootFilesystem: true. The pod filesystem is immutable at runtime. |
| NetworkPolicy | Ingress restricted to the API port (8000) only. Egress restricted to required services (database, knowledge store). No wildcard egress. |
| Resource limits | CPU and memory requests and limits are defined. The pod cannot consume unbounded resources on the node. |
| Pod security standards | Restricted profile enforced. Privilege escalation is blocked. Host namespaces are disabled. |
| Service account | Dedicated service account with minimum required permissions. No cluster-admin, no wildcard RBAC rules. |
CI/CD Security
Security scans run on every pull request and every push to the main branch. No merge lands without passing all checks.
| Tool | Type | Scope |
|---|---|---|
| Bandit | SAST (Static Application Security Testing) | Python source code. Detects common security issues like assert statements, hardcoded passwords, unsafe YAML loading. |
| Trivy | Container vulnerability scanning | Runs on every container build. Scans the final image for known CVEs in OS packages and Python dependencies. |
| GitHub Actions | CI pipeline | Security scans run on every pull request and push. Failures block merge. |
| Dependency review | Supply chain | Automated checks for known vulnerabilities in new dependencies added to requirements files. |
| Secret scanning | Credential leakage | GitHub's built-in secret scanner. Detects API keys, tokens, and private keys committed to the repository. |
Ethics and Content Policy
File: EthicsEngine
Content policy checks run on both input and output. The EthicsEngine evaluates generated content for harmful, biased, or inappropriate material before it reaches the user.
- Input checks: Harmful intent detection, harassment patterns, requests for dangerous content
- Output checks: Bias detection, harmful content filtering, inappropriate material screening
- Configuration: Policies are defined in a JSON configuration file. Operators can adjust thresholds and categories without code changes.
- Logging: Every ethics decision is logged with the category, the action taken, and the relevant content hash.
Security Testing
Security is verified by automated tests on every CI run. The test suite covers authentication, rate limiting, CORS, input injection, and output PII detection.
| Test Group | Count | Coverage |
|---|---|---|
| API security tests | 11 | Auth required, invalid keys, rate limiting, CORS headers |
| Output security tests | 5 | PII detection, secret leakage, prompt injection echo |
| Total | 16 | All pass on every CI run |
Tests cover the negative paths. Missing authentication returns 401. Invalid keys return 401. Rate limit violations return 429. Input injection attempts are blocked. Output PII is caught. These tests run on every pull request. A regression in any of them blocks the merge.
Known Limitations
No security architecture is finished. The following limitations are documented here so operators can plan around them.
| Limitation | Current State | Mitigation |
|---|---|---|
| No OAuth2 or JWT support | API key authentication only. No token refresh, no scoped grants, no delegation. | Use an API gateway or reverse proxy with OAuth2 support in front of the application. |
| No TLS termination in the application | The application serves HTTP. TLS is not handled in process. | Terminate TLS at the reverse proxy or load balancer. The application never sees the private key. |
| No audit log persistence | Security logs go to stdout. They are not written to a persistent store by the application. | Forward stdout to a log aggregation service (ELK, Loki, CloudWatch). Retention is handled at the infrastructure layer. |
| Rate limiting is per-process | Each worker process maintains its own counter. A client hitting multiple workers gets an effective limit multiplied by the worker count. | Use an external rate limiter (Redis, API gateway) for distributed enforcement in multi-replica deployments. |
Responsible Disclosure Policy
If you believe you have found a security vulnerability in Condrox AI, the pre-release chat, or this website, please report it responsibly. We take all reports seriously and will work with you to understand and address the issue.
How to Report
- Email: kontakt@pcnorge.no
- Subject line: "Security Vulnerability Report - [brief summary]"
- Include: A description of the vulnerability, the steps to reproduce it, the potential impact, and any suggested remediation. If possible, use PGP-encrypted email. A public PGP key will be published here once available.
- Do not: Publish the vulnerability details publicly, attempt to access data that does not belong to you, degrade the service for other users, or use the vulnerability for personal gain.
What We Commit To
- Acknowledgement: We will acknowledge receipt of your report within 48 hours.
- Initial assessment: We will provide an initial assessment of the report within 7 days, including whether we have been able to reproduce the issue.
- Updates: For valid vulnerabilities, we will provide status updates at least every 14 days until the issue is resolved or a remediation plan is published.
- Resolution disclosure: We will work with you on a coordinated disclosure timeline. We will not publish details of the vulnerability until a fix is available, and we will credit you in the disclosure unless you prefer to remain anonymous.
- Safe harbor: We will not pursue legal action against reporters who act in good faith, follow this policy, and do not access data that is not their own or degrade the service for others.
Scope
This policy applies to:
- The website at pcnorge.no and all its pages.
- The pre-release chat endpoint exposed via Cloudflare Tunnel.
- The Condrox AI software itself, if you have been granted source code access for evaluation.
This policy does not apply to:
- Vulnerabilities in third-party services (Cloudflare, hosting provider, email provider). Report those to the respective provider.
- Vulnerabilities requiring physical access to hardware we do not control.
- Denial-of-service attacks against the pre-release service. The service is pre-release and runs on a single machine; it is not engineered for high availability. Do not perform load testing or DoS without explicit written permission.
- Automated scanner output without manual verification and a working proof of concept.
Rewards
We do not currently operate a paid bug bounty program. Valid vulnerability reports will be acknowledged publicly (with your permission) and we will work with you on coordinated disclosure. As the project matures, a formal bug bounty program may be introduced.