Files
rengine/shared/definitions/notes.py
T
Yogesh OjhaandClaude Sonnet 5 118728a968 feat(secrets): mine stored responses for exposed credentials
Seventh surface dimension. Passive response mining for credentials,
tokens, keys and contacts already stored in http_assets bodies and
headers — no request is ever sent, no key is tested for validity.

- shared/definitions/secrets.py: 44 detectors across cloud, code,
  payments, messaging, AI, auth, data, platform and contact groups
- shared/services/secret_mining/: detector sweep, the only writer of
  secrets/secret_sightings/secret_coverage, fingerprint + context
- stages/secret_mining/: one stage, one knob, on by default, off
  under passive intensity via touches_target=False
- shared/services/asset_query/secret_compiler.py + the SECRET_QUERY
  grammar: is:exposed / is:new / group: / secret: / state: search
- api/app/services/secret.py + api/app/api/v1/secrets.py: search,
  facets, coverage, groups, detail
- worker/app/tasks/secrets.py: backfill beat for scans mined before
  the stage existed
- Frontend: secrets table and detail sheet built to match the scans
  table (plain values, soft state badges, no explanatory copy),
  own query bar, coverage strip, quick filters
- Wired into every SURFACE_ORDER fan-out (surface scope, dashboard,
  reports, rescan, scan compare, notes, MCP)
- Wired into scan compare (SPECS/COMPARE_KEYS/WATCHED_FIELDS) and
  notes (ASSET_IDENTITY)

Values are stored and shown plain, no encryption, no masking, no
reveal endpoint, no audit trail — a stored value is already exposed
the moment the response was read.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XpxhGvFNFCcEEf4gZykvka
2026-09-15 05:55:23 +05:30

38 lines
960 B
Python

"""Note anchors, and the asset identity each dimension uses."""
from __future__ import annotations
from enum import StrEnum
from shared.definitions.surface import SurfaceDimension
class NoteStatus(StrEnum):
OPEN = "open"
RESOLVED = "resolved"
NOTE_STATUSES: tuple[str, ...] = tuple(s.value for s in NoteStatus)
MAX_NOTE_BODY = 20000
MAX_NOTE_TITLE = 200
MAX_NOTE_TAGS = 20
MAX_ASSET_KEY = 500
MAX_ASSET_LABEL = 500
# each dimension's identity column
ASSET_IDENTITY: dict[str, str] = {
SurfaceDimension.WEB_ASSETS.value: "name",
SurfaceDimension.ENDPOINTS.value: "signature",
SurfaceDimension.SERVICES.value: "ip",
SurfaceDimension.IPS.value: "ip",
SurfaceDimension.VULNERABILITIES.value: "fingerprint",
SurfaceDimension.SOFTWARE.value: "fingerprint",
SurfaceDimension.SECRETS.value: "fingerprint",
}
STATUS_LABELS: dict[str, str] = {
NoteStatus.OPEN.value: "Open",
NoteStatus.RESOLVED.value: "Resolved",
}