Hide RF Links UI elements from network map (TOW-44) (#46)

- Commented out 'View RF Links' button in network map node detail panel
- Commented out RF Link health legend (Good/Degraded/Critical) from map legend
- Backend code (topology.ex) left intact per instructions
- No RF tab found on device show page (nothing to hide there)
- All tests pass, compiles clean with --warnings-as-errors

Reviewed-on: graham/towerops-web#46
This commit is contained in:
Graham McIntire 2026-03-16 15:19:03 -05:00 committed by graham
parent 6321a974a9
commit 26c7b0b993
8 changed files with 399 additions and 1 deletions

View file

@ -1 +1 @@
/nix/store/zx636v118rzzqzwafgrw2aybh7l0szrl-pre-commit-config.json /nix/store/4xlkmdd947h5qlhj2rmbyavq08grkz27-pre-commit-config.json

View file

@ -0,0 +1,44 @@
# Change Management Policy
**Effective:** 2026-03-15
**Owner:** Engineering
## Purpose
All changes to production systems follow a controlled process to prevent outages, data loss, and security regressions.
## Change Categories
| Category | Examples | Process |
|----------|----------|---------|
| **Standard** | Feature work, bug fixes, dependency updates | PR → review → CI → merge → deploy |
| **Expedited** | Security patches (critical/high) | PR → review → CI → merge → immediate deploy |
| **Emergency** | Active incident mitigation | Deploy first → PR + review within 24h |
## Pull Request Requirements
- All changes go through PRs. No direct commits to `main`.
- PRs require at least one approval.
- CI must pass: formatting, credo, dialyzer, sobelow, tests.
- PR description includes: what changed, why, how to test, rollback plan.
- Database migrations reviewed separately for data safety.
## Deployment
- Staging deployment first. Verify core flows work.
- Production deploy during business hours (preferred) unless emergency.
- Monitor error rates and key metrics for 30 minutes post-deploy.
- Rollback plan documented before deploying.
## Database Migrations
- Migrations must be backward-compatible (the old code must work with the new schema during rollout).
- No destructive migrations (DROP TABLE, DROP COLUMN) without a two-phase approach: deprecate → migrate data → remove.
- Large data migrations run as background tasks, not in the migration itself.
- Test migrations against a production-size dataset before deploying.
## Feature Flags
- New features behind feature flags when they affect core workflows.
- Flags default to off in production, on in staging.
- Remove flags within 30 days of full rollout.

54
policies/DATA_HANDLING.md Normal file
View file

@ -0,0 +1,54 @@
# Data Handling & Retention Policy
**Effective:** 2026-03-15
**Owner:** Engineering & Operations
## Purpose
Define how TowerOps stores, processes, backs up, and disposes of customer data to ensure reliability, compliance, and trust.
## Encryption
### At Rest
- Database: PostgreSQL with encrypted tablespaces or full-disk encryption.
- Secrets (API keys, SNMP communities, integration tokens): encrypted using application-level encryption (`Cloak` or equivalent) before storage.
- Backups: encrypted before writing to storage.
### In Transit
- All external connections over TLS 1.2+.
- Internal service-to-service: TLS or encrypted tunnel (Cloudflare Tunnel, WireGuard).
- SNMP v3 preferred where supported; v1/v2c community strings treated as secrets.
## Backups
- Database: daily automated backups with point-in-time recovery.
- Backup retention: 30 days.
- Backup restoration tested quarterly.
- Backups stored in a separate location from primary data.
## Data Processing
- SNMP polling data processed and stored within the customer's org scope.
- No cross-org data aggregation without explicit anonymization.
- Metrics downsampled after retention window (raw → hourly → daily).
- Background jobs operate within org context; job payloads contain `org_id`.
## Data Disposal
- Deleted records soft-deleted for 30-day grace period, then hard-purged.
- Purge jobs run nightly to remove expired soft-deleted records.
- Customer account deletion triggers full data purge after grace period.
- Credentials from revoked integrations deleted immediately (no grace period).
## Access Controls
- Role-based access: `owner`, `admin`, `member`, `viewer`.
- API tokens scoped to organization; cannot access other orgs.
- Token rotation supported; old tokens invalidated on rotation.
- Session timeout: 24 hours idle, 7 days absolute.
## Audit Trail
- All data mutations logged: who (user/agent), what (action), when (timestamp), context (org, resource).
- Audit logs immutable — append-only, no deletion.
- Retained for 1 year minimum.

View file

@ -0,0 +1,93 @@
# Elixir Code Standards Policy
**Effective:** 2026-03-15
**Owner:** Engineering
## Purpose
All Elixir code in TowerOps must be idiomatic, readable, and maintainable. This policy ensures consistency across the codebase and reduces cognitive load for contributors.
## Standards
### Pattern Matching Over Conditionals
- Use pattern matching in function heads instead of `if`/`case` when branching on structure.
- Prefer multi-clause functions over nested conditionals.
```elixir
# Good
def process(%{status: :active} = device), do: ...
def process(%{status: :inactive} = device), do: ...
# Avoid
def process(device) do
if device.status == :active do
...
else
...
end
end
```
### The Pipe Operator
- Use `|>` for data transformation chains (3+ steps).
- Never start a pipe with a raw value — assign or wrap it.
- Each step in a pipe should take the piped value as its first argument.
### With Clauses
- Use `with` for sequences of dependent operations that may fail.
- Always include an `else` clause that handles expected error shapes.
- Keep `with` chains under 5 clauses; extract helpers if longer.
### Naming
- Modules: `PascalCase`, mirroring directory structure.
- Functions: `snake_case`, verb-first (`fetch_device/1`, `parse_response/1`).
- Private helpers: prefix with intent, not `do_` (e.g., `build_query` not `do_query`).
- Boolean functions: end with `?` (e.g., `active?/1`).
### Contexts (Phoenix)
- Business logic lives in context modules (`Towerops.Devices`, `Towerops.Alerts`).
- LiveViews and controllers call contexts — never Repo directly.
- Contexts return `{:ok, result}` or `{:error, reason}` tuples.
- Keep context functions focused; one public function per use case.
### Error Handling
- Use tagged tuples (`{:ok, _}` / `{:error, _}`) for expected failures.
- Let unexpected failures crash — the supervisor will restart.
- Never rescue broadly (`rescue e ->`) without re-raising or logging.
- Use `Ecto.Multi` for operations that must be atomic.
### Documentation
- All public functions must have `@doc` and `@spec`.
- Modules must have `@moduledoc` describing purpose and responsibilities.
- Internal/private functions: document with comments only when non-obvious.
### Testing
- Every public context function must have tests.
- Use `ExUnit.CaseTemplate` and factories for setup.
- Async tests (`async: true`) unless they touch shared state (database).
- Name tests descriptively: `"fetch_device/1 returns error when device not found"`.
### Formatting
- Run `mix format` before every commit. CI will reject unformatted code.
- Use `.formatter.exs` settings; do not override line length (98 chars).
### Dependencies
- Minimize external dependencies. Prefer stdlib and OTP.
- Every new dependency requires a brief justification in the PR description.
- Pin versions explicitly in `mix.exs`.
## Enforcement
- CI runs `mix format --check-formatted`, `mix credo --strict`, and `mix dialyzer`.
- Code review required for all merges to `main`.
- Violations block merge.

View file

@ -0,0 +1,44 @@
# Incident Response Policy
**Effective:** 2026-03-15
**Owner:** Engineering & Operations
## Purpose
Define how TowerOps detects, responds to, and recovers from production incidents to minimize customer impact and maintain trust.
## Severity Levels
| Level | Definition | Response Target | Examples |
|-------|-----------|----------------|----------|
| **SEV-1** | Service down, data loss risk, security breach | 15 minutes | Database corruption, auth bypass, full outage |
| **SEV-2** | Major feature broken, degraded for many customers | 1 hour | Polling failures, alert delivery broken, dashboard errors |
| **SEV-3** | Minor feature issue, workaround exists | 4 hours | UI glitch, non-critical integration failure |
| **SEV-4** | Cosmetic, no customer impact | Next business day | Typo, minor styling issue |
## Response Procedure
1. **Detect** — Monitoring alerts, customer report, or internal discovery.
2. **Acknowledge** — Responder claims the incident within response target.
3. **Assess** — Determine severity, blast radius, and root cause hypothesis.
4. **Mitigate** — Stop the bleeding. Rollback, feature flag, or hotfix.
5. **Resolve** — Fix the root cause. Deploy. Verify.
6. **Communicate** — Notify affected customers. Update status page.
7. **Post-mortem** — Blameless review within 5 business days for SEV-1/SEV-2.
## Communication
- SEV-1/SEV-2: Customer notification within 1 hour of detection.
- Status page updated for all SEV-1/SEV-2 incidents.
- Post-mortem shared with affected customers for SEV-1.
## Post-Mortem Template
Every SEV-1/SEV-2 post-mortem must include:
- Timeline of events
- Root cause analysis
- Impact assessment (customers affected, duration)
- What went well
- What went poorly
- Action items with owners and due dates

22
policies/README.md Normal file
View file

@ -0,0 +1,22 @@
# TowerOps Policies
Company policies governing code quality, security, privacy, and operations.
## Policies
| Policy | Description |
|--------|-------------|
| [Elixir Code Standards](ELIXIR_CODE_STANDARDS.md) | Idiomatic Elixir patterns, naming, testing, and formatting requirements |
| [Security & Vulnerability Prevention](SECURITY_AND_VULNERABILITY.md) | Pre-commit security checklist, dependency auditing, vulnerability response |
| [User Privacy](USER_PRIVACY.md) | Data classification, multi-tenant isolation, retention, export/deletion |
| [Incident Response](INCIDENT_RESPONSE.md) | Severity levels, response procedures, communication, post-mortems |
| [Change Management](CHANGE_MANAGEMENT.md) | PR process, deployment procedures, database migration safety |
| [Data Handling & Retention](DATA_HANDLING.md) | Encryption, backups, data processing, disposal, access controls |
## Enforcement
These policies are enforced through:
1. **CI/CD** — Automated checks (formatting, credo, sobelow, dialyzer, tests)
2. **Code review** — Required for all PRs
3. **Quarterly reviews** — Policies reviewed and updated as the product evolves

View file

@ -0,0 +1,64 @@
# Security & Vulnerability Prevention Policy
**Effective:** 2026-03-15
**Owner:** Engineering
## Purpose
Every commit must be evaluated for security implications before merge. TowerOps handles network infrastructure data — a breach could expose customer network topologies, credentials, and operational data.
## Pre-Commit Security Checklist
Before committing, verify:
1. **No hardcoded secrets.** No API keys, tokens, passwords, or SNMP community strings in source. Use environment variables or runtime config.
2. **No SQL/HQL injection.** All database queries use parameterized Ecto queries — never string interpolation in queries.
3. **No LIKE injection.** Sanitize `%` and `_` in user-provided LIKE patterns using `Towerops.Helpers.sanitize_like/1`.
4. **Input validation.** All user input passes through Ecto changesets with explicit casting and validation before reaching business logic.
5. **Authorization checks.** Every controller/LiveView action verifies the current user has access to the requested resource via org membership.
6. **No mass assignment.** Changesets explicitly list permitted fields — never pass raw params to `cast/3` without filtering.
7. **Credential stripping.** API responses that include integration configs must strip `password`, `token`, `secret`, `api_key`, and `community` fields.
## Dependency Security
- Run `mix deps.audit` (via `mix_audit`) weekly and before releases.
- Run `mix sobelow` for static security analysis on every PR.
- Update dependencies monthly; patch critical CVEs within 48 hours.
- Erlang/OTP and Elixir versions must be on supported release tracks.
## Authentication & Sessions
- All sessions use secure, HTTP-only, SameSite=Lax cookies.
- Session tokens are rotated on privilege escalation (login, role change).
- API tokens are bearer tokens — never transmitted in query strings.
- Failed login attempts are rate-limited.
- Passwords hashed with `bcrypt` (Argon2 acceptable alternative).
## Network Security
- All external traffic over TLS. No exceptions.
- SNMP community strings treated as secrets — stored encrypted at rest, never logged.
- Agent-to-server communication uses mTLS or token-based auth with TOFU host key verification.
- Webhook endpoints validate signatures where supported.
- GraphQL introspection disabled in production.
## Logging
- Log security-relevant events: login, logout, failed auth, permission changes, data export.
- Never log credentials, tokens, full request bodies with sensitive fields, or PII.
- Retain security logs for 90 days minimum.
## Vulnerability Response
| Severity | Response Time | Action |
|----------|--------------|--------|
| Critical (RCE, auth bypass, data leak) | 4 hours | Patch, deploy, notify affected customers |
| High (privilege escalation, injection) | 24 hours | Patch, deploy |
| Medium (information disclosure, DoS) | 1 week | Patch in next release |
| Low (best practice deviation) | 1 month | Track in backlog |
## Enforcement
- CI runs `mix sobelow --exit` on every PR.
- `mix deps.audit` integrated into CI pipeline.
- Security-sensitive PRs (auth, crypto, data access) require explicit review from a senior engineer.

77
policies/USER_PRIVACY.md Normal file
View file

@ -0,0 +1,77 @@
# User Privacy Policy
**Effective:** 2026-03-15
**Owner:** Engineering & Operations
## Purpose
TowerOps monitors network infrastructure for ISPs and managed service providers. We handle sensitive operational data — device configurations, network topologies, traffic patterns, and customer metadata. This policy defines how we protect that data.
## Core Principles
1. **Collect only what's needed.** Never store data we don't have a clear product use for.
2. **Isolate by organization.** One customer must never see another customer's data. Ever.
3. **Encrypt in transit and at rest.** No exceptions.
4. **Default to private.** New features default to most-restrictive access.
5. **Delete when asked.** Customers can request full data deletion, and we comply promptly.
## Data Classification
| Classification | Examples | Handling |
|---------------|----------|----------|
| **Critical** | SNMP community strings, API keys, integration credentials | Encrypted at rest, never logged, stripped from API responses, access-audited |
| **Sensitive** | Device configs, network topologies, alert rules, user emails | Encrypted at rest, org-scoped access only, included in data export |
| **Operational** | Metrics, performance data, SNMP poll results | Org-scoped, retained per retention policy, aggregatable |
| **Public** | Product documentation, pricing | No restrictions |
## Multi-Tenancy Isolation
- All database queries MUST scope to the current user's organization via `org_id`.
- Row-Level Security (RLS) or application-level scoping enforced on every query.
- Background jobs (SNMP polling, alert evaluation) scope to their org context.
- Shared infrastructure (TimescaleDB, Redis) uses logical separation with org-prefixed keys.
- Cross-org data access is impossible by design — no admin backdoor, no superuser query mode.
## Data Retention
| Data Type | Default Retention | Customer Override |
|-----------|------------------|-------------------|
| SNMP metrics | 90 days raw, 2 years downsampled | Configurable |
| Alert history | 1 year | Configurable |
| Audit logs | 1 year | Minimum, not reducible |
| User sessions | 30 days | Not configurable |
| Deleted accounts | 30 days grace, then purged | Immediate on request |
## Data Export & Deletion
- Customers can export all their data via API (`GET /api/export`).
- Account deletion removes all org data within 30 days.
- Deletion requests logged and confirmed via email.
- Backups rotate out deleted data within the backup retention window (30 days).
## Employee & Agent Access
- Engineers access production data only through audited tooling — no direct database shells.
- AI agents (TowerOps agent, Paperclip agents) operate within org scope and cannot access other orgs.
- All production access logged with who, when, what, and why.
- Access reviewed quarterly; unused access revoked.
## Third-Party Integrations
- Integration credentials (PagerDuty, Gaiia, Sonar, etc.) stored encrypted.
- We send only the minimum data required for the integration to function.
- Integration data flows are documented per integration.
- Customers can revoke integrations at any time; credentials are deleted immediately.
## Incident Response (Privacy)
- Data breaches reported to affected customers within 72 hours.
- Breach scope assessed within 24 hours.
- Post-mortem published internally within 1 week.
- Regulatory notifications (if applicable) within required timelines.
## Enforcement
- Code review checks org-scoping on all data access.
- Automated tests verify tenant isolation.
- Quarterly privacy review of new features.