Documentation
¶
Overview ¶
S77-T08: doctor --deep check for orphaned Hasura remote schemas.
A remote schema is "orphaned" when it is registered in Hasura metadata but the plugin that provides it is no longer installed. This can happen after `nself plugin uninstall <name>` if Hasura metadata was not cleaned up, or after a manual plugin removal. Orphaned remote schemas cause Hasura to emit schema-load errors on startup and break the GraphQL API surface.
Detection strategy:
- Read NSELF_HASURA_GRAPHQL_URL (or derive from HASURA_GRAPHQL_URL) to locate the running Hasura instance.
- Call the Hasura Metadata API to export remote_schemas (POST /v1/metadata with {"type":"export_metadata","args":{}}). Requires HASURA_GRAPHQL_ADMIN_SECRET.
- For each remote schema entry, derive the expected plugin name from the remote schema's URL: internal plugin URLs follow the pattern http://host:PORT where PORT is registered in PLUGIN_<NAME>_INTERNAL_URL.
- Cross-reference against loaded plugins: env var NSELF_PLUGINS_LOADED (comma- separated list set by `nself build`) and per-plugin PLUGIN_<NAME>_INTERNAL_URL.
- Emit WARN for each orphan found; PASS if none; SKIP if Hasura is unreachable.
The check is read-only — it never modifies Hasura metadata. S77-T08
legal_coppa.go implements the LEGAL-COPPA-01 deep doctor check.
LEGAL-COPPA-01 verifies that the COPPA parental-consent flow shipped in the family plugin is wired correctly before the nFamily product can be marked production-ready.
The check is layered:
pass — migration present, consent secret env set, TTL within policy
warn — migration present but FAMILY_CONSENT_HMAC_SECRET unset, or TTL
above the policy ceiling, or the family plugin is loaded without
the migration on disk
fail — family plugin loaded AND migration file missing entirely (the
parental-consent flow cannot work without the schema)
skip — family plugin not loaded; the check is not applicable
The Hasura row-level accessibility of np_parental_consents is verified by the existing PERM-HASURA-01 / PERM-RLS-01 checks (np_* tables are blanket covered there). LEGAL-COPPA-01 stays focused on the COPPA-specific preconditions: schema present, signing secret set, TTL within policy.
S12.T06 follow-up.
legal_gdpr_a9.go implements the LEGAL-GDPR-A9-01 deep doctor check.
LEGAL-GDPR-A9-01 verifies that the GDPR Article 9 special-category consent flow shipped in the family plugin is wired correctly before the nFamily product can be marked production-ready.
The check is layered:
pass — np_family_consents migration on disk AND the privacy page
contains the GDPR Article 9 disclosure section
warn — migration on disk but the privacy page is missing the Article 9
disclosure, or NSELF_DPO_EMAIL is unset (recommended for any
deployment processing special-category data)
fail — family plugin loaded AND np_family_consents migration absent
skip — family plugin not loaded; the check is not applicable
The runtime accessibility of np_family_consents is covered by the existing PERM-RLS-01 check (np_* RLS sweep). LEGAL-GDPR-A9-01 stays focused on Article 9 preconditions: schema present, privacy disclosure present, DPO contact recorded.
S12.T07 follow-up.
S69-T05: doctor check for ai+moderation wiring on public-bound deployments.
If the ai plugin is loaded AND the deployment binding is non-loopback AND the moderation plugin is NOT loaded, this emits a WARN. Severity is WARN (not FAIL) because self-hosted single-user setups are legitimate.
S12.T01 — doctor check OBS-SCRAPE-01.
When any ɳSentry plugin (nself-uptime-monitor, nself-status-page, nself-incident-mgmt, nself-alert-router, nself-slo-tracker, nself-synthetic-monitor, nself-rum) is installed, the generated monitoring/prometheus.yml MUST contain a scrape-target stanza for each installed plugin (job name "nsentry-<slug>").
Severity: WARN. Missing stanzas mean Prometheus is not scraping the plugin's /metrics endpoint, but the plugin itself still runs — degraded observability, not broken functionality.
Package doctor — ops_drill.go: OPS-DRILL-01 check.
Verifies that a successful `nself backup drill` ran within the last 7 days. The drill log lives at <projectDir>/.nself/drill-log.json (JSON Lines format, written by internal/backup.Drill). The check is read-only and never invokes the drill itself — that would be a privileged operation gated by SSH.
Status semantics:
- PASS: most recent successful drill within 7 days
- WARN: most recent successful drill 7–14 days old (operator nudge)
- FAIL: no successful drill found OR most recent > 14 days
The fix-cmd suggests `nself backup drill` so operators can run it manually or wire the weekly cron via scripts/dr-drill.sh.
Package doctor — redact_audit.go: doctor check OBS-REDACT-01.
Verifies that a synthetic telemetry-shaped payload, after passing through observability.Redact, contains no patterns matching the canonical PII regexes (email, IPv4 [non-loopback], IPv6 [non-loopback], JWT). Catches regressions in redact.go where a pattern is silently removed or weakened.
Severity: WARN. A redaction regression does not break the CLI but does degrade the privacy guarantees documented in .claude/docs/operations/telemetry-privacy.md.
Package doctor — rls_check_nsentry.go
ɳSentry-specific RLS checks (NSENTRY-RLS-01..07).
When any of the 7 ɳSentry baseline plugins is installed, nself doctor --deep verifies that its np_* tables have:
- RLS enabled (relrowsecurity = true)
- At least one policy
- FORCE RLS when a tenant_id column is present
- A Hasura row filter for tenant_id ({"tenant_id":{"_eq":"X-Hasura-Tenant-Id"}})
Each of the 7 plugins gets its own check ID (NSENTRY-RLS-01..07) and runs only when that plugin's plugin.json is present in pluginDir.
Severity: CRITICAL — RLS misconfiguration on ɳSentry tables exposes uptime, incident, and SLO data across tenants.
Security-Always-Free Doctrine: these checks run without a license.
Package doctor provides comprehensive health check sections for nself doctor.
Index ¶
- Constants
- func DeadAddr(err error) bool
- func LoadConfigIsolated(dir string) (*config.Config, error)
- func LoadConfigIsolatedLookup(dir string, keys ...string) (*config.Config, map[string]string, error)
- func PasswordNeedsURLEncoding(pw string) bool
- func RawPasswordInURL(fragment, name string) bool
- func RecommendedPoolSize(postgresMaxConnections, numServices int) int
- func RecordCITokenRotation(projectDir string) error
- func RegisterExternal(name string, fn ExternalFunc)
- func ServedTLSAddressEnv(root, projectDir string, cfg *config.Config) (map[string]string, error)
- func URLReservedFindings(passwords map[string]string, fragments []string) []string
- func URLReservedMessages(paths []string, passwords map[string]string) []string
- type CheckResult
- func BackupChecks(_ context.Context, projectDir string) []CheckResult
- func BackupHintChecks(projectDir string) []CheckResult
- func BundleLedgerDriftChecks(_ context.Context, pluginDir string) []CheckResult
- func CheckAdminBind(ctx context.Context) CheckResult
- func CheckCIToken(projectDir string) CheckResult
- func CheckCIVaultSync(projectDir string) CheckResult
- func CheckEncryptionKeyScope(projectDir string, strict bool) []CheckResult
- func CheckHasuraIntrospection(_ context.Context) CheckResult
- func CheckHasuraMetadataBackup(backupDir string) CheckResult
- func CheckHasuraMetadataYAML(_ context.Context, projectDir string, strict bool) []CheckResult
- func CheckJWTRotation(projectDir string) CheckResult
- func CheckJWTSecretPresent(projectDir string) CheckResult
- func CheckLegalCOPPA(projectDir string) CheckResult
- func CheckLegalGDPRA9(projectDir string) CheckResult
- func CheckMinioCredentials() CheckResult
- func CheckModerationWired(_ context.Context) CheckResult
- func CheckNSelfAuditScan(ctx context.Context, projectDir string) []CheckResult
- func CheckNSentryRLS(ctx context.Context, pluginDir string) []CheckResult
- func CheckOBSScrape(_ context.Context, projectDir, pluginDir string) CheckResult
- func CheckOPSDrill(_ context.Context, projectDir string) CheckResult
- func CheckOrphanRemoteSchemas(ctx context.Context) CheckResult
- func CheckPayPalCSVParity(ctx context.Context) CheckResult
- func CheckProxyDockerSocket(ctx context.Context, ins SocketInspector, rep *socketInventory) CheckResult
- func CheckRLSEnforcement(ctx context.Context, strict bool) []CheckResult
- func CheckRedactionCoverage(_ context.Context) CheckResult
- func CheckSDKVersions(ctx context.Context) []CheckResult
- func CheckSSLTracked(ctx context.Context, projectDir string) CheckResult
- func CheckSSRF(projectDir string) CheckResult
- func DeepChecks(ctx context.Context, projectDir string, verbose bool) []CheckResult
- func DockerDeepChecks(ctx context.Context, verbose bool) []CheckResult
- func DockerSocketChecks(ctx context.Context, projectDir string) []CheckResult
- func DogfoodChecks(ctx context.Context, projectDir string, verbose bool) []CheckResult
- func EntitlementFileChecks(_ context.Context, projectDir string) []CheckResult
- func EntitlementTimerChecks(_ context.Context, projectDir string) []CheckResult
- func ExternalChecks(ctx context.Context, projectDir string) []CheckResult
- func FilterBySection(results []CheckResult, section string) []CheckResult
- func FixItEngine(ctx context.Context, projectDir string, results []CheckResult) []CheckResult
- func HardeningChecks(ctx context.Context, projectDir string) []CheckResult
- func HasuraChecks(ctx context.Context, verbose bool) []CheckResult
- func HostChecks(ctx context.Context, verbose bool) []CheckResult
- func IsolationChecks(ctx context.Context, projectDir string) []CheckResult
- func LicenseChecks(ctx context.Context, projectDir string, verbose bool) []CheckResult
- func MonitoringChecks(ctx context.Context) []CheckResult
- func NginxChecks(ctx context.Context, projectDir string, verbose bool) []CheckResult
- func PingChecks(ctx context.Context, verbose bool) []CheckResult
- func PluginHealthChecks(ctx context.Context, projectDir string, verbose bool) []CheckResult
- func PluginMigrationChecks(ctx context.Context, pluginDir string) []CheckResult
- func PoolCapacityCheck(_ context.Context, pools []PoolConfig, postgresMaxConnections int) CheckResult
- func PostgresChecks(ctx context.Context, projectDir string, verbose bool) []CheckResult
- func SSLChecks(ctx context.Context, verbose bool) []CheckResult
- func SecurityChecks(ctx context.Context, projectDir string) []CheckResult
- func SystemChecks(ctx context.Context, verbose bool) []CheckResult
- func VectorSearchChecks(ctx context.Context, projectDir string) []CheckResult
- type ExternalFunc
- type PoolConfig
- type SocketInspector
Constants ¶
const ( // DefaultPostgresMaxConnections is the Postgres default max_connections setting. // Operators should raise this in POSTGRES_MAX_CONNECTIONS when running many services. DefaultPostgresMaxConnections = 100 // PoolCapCheckID is the canonical check ID referenced in docs and Alertmanager. PoolCapCheckID = "PERF-POOL-01" )
const (
// HasuraMetaCheckID is the canonical check ID referenced in docs and wiki.
HasuraMetaCheckID = "PERM-HASURA-01"
)
const (
// HintPrefix marks a hint that fired.
HintPrefix = "advisory: "
)
const (
// RLSCheckID is the canonical check ID referenced in docs, wiki, and Alertmanager.
RLSCheckID = "PERM-RLS-01"
)
Variables ¶
This section is empty.
Functions ¶
func DeadAddr ¶ added in v1.4.13
DeadAddr reports whether a probe error means the address itself is down (a failed dial), so every other host on it would fail the same way. A handshake timeout can be specific to one SNI and must not suppress the remaining hosts.
func LoadConfigIsolated ¶ added in v1.4.13
LoadConfigIsolated is config.Load for the project with the process environment put back afterwards: Load overlays the .env cascade onto it, and a check must not change what later code sees.
func LoadConfigIsolatedLookup ¶ added in v1.4.14
func LoadConfigIsolatedLookup(dir string, keys ...string) (*config.Config, map[string]string, error)
LoadConfigIsolatedLookup is LoadConfigIsolated that also returns the values the project's .env cascade gives the named keys (read while Load's overlay is in place, before the environment is put back). An unset key is absent.
func PasswordNeedsURLEncoding ¶ added in v1.4.13
PasswordNeedsURLEncoding reports whether pw changes under URL userinfo encoding, i.e. whether embedding it raw in a URL would break the URL.
func RawPasswordInURL ¶ added in v1.4.13
RawPasswordInURL reports whether fragment embeds ${name} raw inside a URL (a line holding "://" with the variable after it). The safe nested form ${NAME_URLENC:-${NAME}} is not raw use and is ignored; so are comments.
func RecommendedPoolSize ¶ added in v1.0.11
RecommendedPoolSize computes the recommended per-service MaxConns cap.
MaxConns = min(10, floor(postgres_max_connections / num_services))
Edge cases:
- numServices=0 → returns 10 (no services, no constraint)
- very large max_connections → capped at 10 (prevents runaway allocations)
- numServices > max_connections → returns 1 (absolute minimum)
func RecordCITokenRotation ¶ added in v1.0.14
RecordCITokenRotation writes a new timestamp to the rotation log. Called by `nself doctor --record-ci-token-rotation`. Creates parent dirs as needed.
func RegisterExternal ¶ added in v1.4.15
func RegisterExternal(name string, fn ExternalFunc)
RegisterExternal adds (or replaces) the provider registered under name.
func ServedTLSAddressEnv ¶ added in v1.4.15
ServedTLSAddressEnv resolves the serving stack's bind IP and TLS port. Own stacks use the loaded config's full env cascade; fronted stacks read their own env without changing the process environment.
func URLReservedFindings ¶ added in v1.4.13
URLReservedFindings returns, sorted, the names of the passwords (keys of passwords) that need URL encoding and are still embedded raw in a URL in at least one of fragments. Values of passwords are read, never returned.
func URLReservedMessages ¶ added in v1.4.13
URLReservedMessages reads the fragment files at paths (unreadable files are skipped: advisory, never an error) and returns one warning per password variable found raw in a URL. A message names the variable and the fix, never the password.
Types ¶
type CheckResult ¶
type CheckResult struct {
Section string `json:"section"`
Name string `json:"name"`
Status string `json:"status"` // pass, warn, fail
Message string `json:"message"`
FixCmd string `json:"fix_cmd,omitempty"` // suggested fix command
}
CheckResult holds the outcome of a single diagnostic check.
func BackupChecks ¶
func BackupChecks(_ context.Context, projectDir string) []CheckResult
BackupChecks verifies backup health.
func BackupHintChecks ¶ added in v1.4.13
func BackupHintChecks(projectDir string) []CheckResult
BackupHintChecks returns the advisory backup hints for projectDir.
func BundleLedgerDriftChecks ¶ added in v1.4.13
func BundleLedgerDriftChecks(_ context.Context, pluginDir string) []CheckResult
BundleLedgerDriftChecks is the DeepChecks entry point.
func CheckAdminBind ¶ added in v1.0.11
func CheckAdminBind(ctx context.Context) CheckResult
CheckAdminBind verifies that the nself-admin container is bound to 127.0.0.1 only (not 0.0.0.0 which would expose it to the LAN). This implements S43-T03 — required by the Service Binding Hard Rule.
func CheckCIToken ¶ added in v1.0.14
func CheckCIToken(projectDir string) CheckResult
CheckCIToken is the CI-TOKEN-01 deep doctor check.
It verifies:
- NSELF_CI_TOKEN is set (in any env cascade file or the environment itself).
- A rotation log exists documenting the last time the token was rotated.
- Expiry-proximity check (primary): if an "expires <RFC3339>" entry exists in the rotation log, warn at ≤14d remaining and fail at ≤1d remaining.
- Rotation-age check (fallback): when no expiry date is present in the log (legacy entries), fall back to the old 90d soft / 120d hard rotation-age logic.
This check is --deep only. It does NOT attempt to call the GitHub API (no network) — it only inspects the local rotation log.
To update the rotation log after a token rotation:
nself doctor --record-ci-token-rotation [--expires <RFC3339>]
(CLI command delegates to internal/doctor.RecordCITokenRotation.)
func CheckCIVaultSync ¶ added in v1.0.14
func CheckCIVaultSync(projectDir string) CheckResult
CheckCIVaultSync is the CI-VAULT-SYNC-01 deep doctor check.
It verifies that vault.env or the live environment contains all critical CI PATs (fail on missing) and 180-day infra tokens (warn on missing).
The check does NOT validate token values — only presence. A token could be present but expired; CI-TOKEN-01 handles rotation-age tracking for NSELF_CI_TOKEN specifically. CI-VAULT-SYNC-01 covers the broader vault coverage question.
func CheckEncryptionKeyScope ¶ added in v1.0.11
func CheckEncryptionKeyScope(projectDir string, strict bool) []CheckResult
CheckEncryptionKeyScope verifies that AI_ENCRYPTION_KEY (and any other *_ENCRYPTION_KEY env vars) are set and are not reused across environments. Implements S43-UNDEP-01 + S43-AUDIT-01 (SEC-ENC-01 and SEC-ENC-02).
When strict=true, a shared or default key returns Status="fail". When strict=false (default), it returns Status="warn" — allowing the admin to investigate without blocking a deploy.
func CheckHasuraIntrospection ¶ added in v1.0.11
func CheckHasuraIntrospection(_ context.Context) CheckResult
CheckHasuraIntrospection implements SEC-HASURA-INTRO-01. It warns if HASURA_GRAPHQL_DISABLE_INTROSPECTION is not set to "true" in a production environment (NSELF_ENV=production or NODE_ENV=production).
The check is:
- status "skip": environment is dev/staging or NSELF_ENV is unset/empty
- status "pass": HASURA_GRAPHQL_DISABLE_INTROSPECTION=true in production
- status "warn": HASURA_GRAPHQL_DISABLE_INTROSPECTION absent or not "true" in production
The check is read-only — it never modifies Hasura configuration. S70-T06
func CheckHasuraMetadataBackup ¶ added in v1.0.14
func CheckHasuraMetadataBackup(backupDir string) CheckResult
CheckHasuraMetadataBackup verifies that a hasura-metadata-*.json file exists in backupDir and is less than 36 hours old (implements BACKUP-METADATA-01).
func CheckHasuraMetadataYAML ¶ added in v1.1.0
func CheckHasuraMetadataYAML(_ context.Context, projectDir string, strict bool) []CheckResult
CheckHasuraMetadataYAML implements PERM-HASURA-01.
It walks hasura/metadata/ (and the subdirectory databases/default/tables/ if present) under projectDir, parses every *.yaml file that defines a table, and verifies that each tracked np_* table has the correct user-role row filter.
Rules:
- np_* table with source_account_id in filter → PASS
- np_* table with tenant_id in filter → PASS
- np_* table with neither filter → FAIL (PERM-HASURA-01)
- np_* table with no user select_permission → FAIL (PERM-HASURA-01)
- non-np_* table or table with no isolation col → exempt
Pass strict=true to report failures as "fail" (blocks deploy). Default "warn". ctx is reserved for future cancellation; disk reads are synchronous.
func CheckJWTRotation ¶ added in v1.0.14
func CheckJWTRotation(projectDir string) CheckResult
CheckJWTRotation implements the JWT-ROT-01 deep doctor check. It verifies:
- HASURA_GRAPHQL_JWT_SECRET is set (delegates to CheckJWTSecretPresent for the precise fail/warn/pass logic on where the key lives).
- A rotation log exists at the configured path.
- The last recorded rotation is within the configured window (default 90d).
This check is only included in --deep mode.
func CheckJWTSecretPresent ¶ added in v1.0.7
func CheckJWTSecretPresent(projectDir string) CheckResult
CheckJWTSecretPresent reports whether HASURA_GRAPHQL_JWT_SECRET is defined in any of the project's env files. Semantics:
- fail when the key is absent from both .env and .env.secrets and no other env file has it either; this is what the spec calls "Hasura enabled but JWT secret absent from both sources".
- warn when the key is in .env.secrets but missing from .env. This is the nSelf-preferred arrangement (secrets live in .env.secrets which is gitignored and chmod 0600), so it is informational only.
- pass when the key is present in .env (with or without .env.secrets).
projectDir is the working directory passed through from `nself doctor`.
func CheckLegalCOPPA ¶ added in v1.1.0
func CheckLegalCOPPA(projectDir string) CheckResult
CheckLegalCOPPA implements LEGAL-COPPA-01.
func CheckLegalGDPRA9 ¶ added in v1.1.0
func CheckLegalGDPRA9(projectDir string) CheckResult
CheckLegalGDPRA9 implements LEGAL-GDPR-A9-01.
func CheckMinioCredentials ¶ added in v1.1.8
func CheckMinioCredentials() CheckResult
CheckMinioCredentials reads NSELF_ENV, MINIO_ROOT_USER, and MINIO_ROOT_PASSWORD from the environment and returns a CRITICAL finding when either credential uses the insecure "minioadmin" default in a staging or production deployment. Dev environments are always unblocked.
Check ID: MINIO-CRED-01
func CheckModerationWired ¶ added in v1.0.11
func CheckModerationWired(_ context.Context) CheckResult
CheckModerationWired implements S69-T05: warns when the ai plugin is loaded on a public-bound deployment without the moderation plugin also loaded.
Detection logic:
- ai plugin loaded: NSELF_AI_LOADED=1 OR PLUGIN_AI_INTERNAL_URL non-empty
- moderation plugin loaded: NSELF_MODERATION_LOADED=1 OR PLUGIN_MODERATION_INTERNAL_URL non-empty
- public bind: NSELF_BIND_ADDRESS is NOT 127.x / localhost / ::1 / "" (empty = loopback default)
func CheckNSelfAuditScan ¶ added in v1.1.2
func CheckNSelfAuditScan(ctx context.Context, projectDir string) []CheckResult
CheckNSelfAuditScan dispatches the NSCAN-001..010 rule set to the nself-audit plugin and returns the per-finding CheckResults.
projectDir is used to compute the env file and docker-compose path. When the plugin is not reachable, returns a single "skipped" pass-result rather than a fail (Security-Always-Free contract — the scan is an enhancement, not a blocker for projects that don't have the plugin installed).
func CheckNSentryRLS ¶ added in v1.1.1
func CheckNSentryRLS(ctx context.Context, pluginDir string) []CheckResult
CheckNSentryRLS runs NSENTRY-RLS-01..07 for each installed ɳSentry baseline plugin. A plugin is considered installed when pluginDir/<plugin-name>/plugin.json exists. When none of the 7 baseline plugins are installed, the function returns a single pass result ("nsentry not installed — skipping").
Each per-plugin check delegates to CheckRLSEnforcement (the generic PERM-RLS-01 implementation) and filters to only the np_* tables whose name begins with the plugin's tablePrefix. This avoids re-querying the DB once per plugin; instead a single query fetches all np_* tables and per-plugin results are sliced from that shared list.
Severity escalation: all violations are reported with status "fail" (CRITICAL). This is stricter than the generic PERM-RLS-01 (which uses "warn" by default) because ɳSentry tables hold cross-tenant observability data.
The function accepts pluginDir as a parameter so tests can provide a temp directory without touching the real filesystem.
func CheckOBSScrape ¶ added in v1.1.0
func CheckOBSScrape(_ context.Context, projectDir, pluginDir string) CheckResult
CheckOBSScrape implements OBS-SCRAPE-01 — verifies Prometheus scrape config covers every installed ɳSentry plugin.
projectDir is the user's project root (where monitoring/ lives). pluginDir is the plugin install directory (typically ~/.nself/plugins). When either is empty, the check is skipped (returns pass with explanation).
func CheckOPSDrill ¶ added in v1.1.0
func CheckOPSDrill(_ context.Context, projectDir string) CheckResult
CheckOPSDrill returns the OPS-DRILL-01 result for projectDir. The function is pure read-only — it never mutates filesystem state.
func CheckOrphanRemoteSchemas ¶ added in v1.0.11
func CheckOrphanRemoteSchemas(ctx context.Context) CheckResult
CheckOrphanRemoteSchemas implements S77-T08. It queries Hasura metadata and compares registered remote schemas against the currently installed nself plugins. Any remote schema whose providing plugin is absent is flagged as an orphan.
func CheckPayPalCSVParity ¶ added in v1.1.8
func CheckPayPalCSVParity(ctx context.Context) CheckResult
CheckPayPalCSVParity verifies that PayPal environment variables have matching counts for PAYPAL_CLIENT_IDS and PAYPAL_CLIENT_SECRETS when multi-account mode is enabled. Purpose: Prevent silent mispairing of credentials in multi-account PayPal setups. Inputs: Environment variables (PAYPAL_CLIENT_IDS, PAYPAL_CLIENT_SECRETS). Outputs: CheckResult with status (ok/warn) and message naming the count mismatch if any. Constraints: Runs only when PAYPAL_CLIENT_IDS is set (indicating PayPal is installed).
func CheckProxyDockerSocket ¶ added in v1.4.15
func CheckProxyDockerSocket(ctx context.Context, ins SocketInspector, rep *socketInventory) CheckResult
func CheckRLSEnforcement ¶ added in v1.0.11
func CheckRLSEnforcement(ctx context.Context, strict bool) []CheckResult
CheckRLSEnforcement implements PERM-RLS-01.
It queries Postgres pg_class for every np_* table and verifies:
(a) RLS is enabled (relrowsecurity = true) (b) at least one policy exists (c) PatternTenantScoped tables have FORCE RLS (relforcerowsecurity = true) (d) tables with tenant_id column have Hasura row filter for that column
Violations are WARN by default. Pass strict=true to escalate to fail.
This check is read-only. It never modifies DB state.
func CheckRedactionCoverage ¶ added in v1.1.0
func CheckRedactionCoverage(_ context.Context) CheckResult
CheckRedactionCoverage runs OBS-REDACT-01.
func CheckSDKVersions ¶ added in v1.0.14
func CheckSDKVersions(ctx context.Context) []CheckResult
CheckSDKVersions implements the SDK-VERSION-01 deep doctor check. It returns one CheckResult per SDK (4 total), each independently pass / warn / fail so a single drifted SDK does not mask the others.
func CheckSSLTracked ¶ added in v1.4.14
func CheckSSLTracked(ctx context.Context, projectDir string) CheckResult
CheckSSLTracked reports whether certificate keys under ssl/ and .env.secrets are ignored by git and not already tracked (D-0459).
func CheckSSRF ¶ added in v1.0.14
func CheckSSRF(projectDir string) CheckResult
CheckSSRF implements the SSRF-01 deep doctor check. It locates the plugins-pro paid/ directory relative to projectDir and verifies that each plugin service carries effective SSRF guard code (file present + guard symbol present).
projectDir is the nself project working directory (where .env lives). plugins-pro is expected to be a sibling of cli/ inside the nself monorepo.
func DeepChecks ¶
func DeepChecks(ctx context.Context, projectDir string, verbose bool) []CheckResult
DeepChecks runs all 12 subsystem categories for --deep mode.
func DockerDeepChecks ¶
func DockerDeepChecks(ctx context.Context, verbose bool) []CheckResult
DockerDeepChecks verifies daemon, storage driver, dangling images, container health.
func DockerSocketChecks ¶ added in v1.4.15
func DockerSocketChecks(ctx context.Context, projectDir string) []CheckResult
func DogfoodChecks ¶ added in v1.0.13
func DogfoodChecks(ctx context.Context, projectDir string, verbose bool) []CheckResult
DogfoodChecks runs the full dogfood-only check set. It is invoked from DeepChecks when NSELF_DOGFOOD=1 is set, AND can be invoked directly from CI to gate nself.org's own deploys.
Check IDs (cross-referenced in operations/dogfood-checks.md):
SEC-CSP-01 — CSP headers present on all subapps SEC-HSTS-01 — HSTS preload value SEC-AUTH-01 — HttpOnly cookie convention enforced VENDOR-DEP-01 — no AGPL/SSPL deps in production source DOGFOOD-SUBAPPS-01 — every shipped subapp has synced sport.json DOGFOOD-HEX-01 — no hex colors in subapp src/ trees DOGFOOD-LICENSE-01 — owner license vault path readable
PERM-RLS-01 is intentionally NOT duplicated here; rls_check.go owns it.
func EntitlementFileChecks ¶ added in v1.4.15
func EntitlementFileChecks(_ context.Context, projectDir string) []CheckResult
Purpose: surface E126 before the server-signed entitlement grace runs out. Inputs: project directory and the current time, with a bounded JWT read. Outputs: no finding for free stacks; warning for missing, invalid or stale files. Constraints: read-only, v1.5 only, never trust an unsigned exp or local mtime. SPORT: contract:plugin.entitlement-token v1 (P7-PLUG-24).
func EntitlementTimerChecks ¶ added in v1.4.15
func EntitlementTimerChecks(_ context.Context, projectDir string) []CheckResult
Purpose: surface E132 when a licensed v1.5 stack has no unattended entitlement refresh timer. Inputs: project directory. Outputs: no finding when the timer is active, not wanted (v1.4, free stack, autorefresh disabled, custom plugin directory) or Windows; otherwise one warning. Constraints: read-only, never installs the timer, never prints a path, key or token. SPORT: cap:cli.entitlement-autorefresh (P7-PLUG-64).
func ExternalChecks ¶ added in v1.4.15
func ExternalChecks(ctx context.Context, projectDir string) []CheckResult
ExternalChecks runs every registered provider in name order and returns their results concatenated. It returns nil when none is registered.
func FilterBySection ¶
func FilterBySection(results []CheckResult, section string) []CheckResult
FilterBySection returns only checks matching the given section name.
func FixItEngine ¶
func FixItEngine(ctx context.Context, projectDir string, results []CheckResult) []CheckResult
FixItEngine runs safe auto-fixes for check results that have FixCmd set.
func HardeningChecks ¶ added in v1.1.0
func HardeningChecks(ctx context.Context, projectDir string) []CheckResult
HardeningChecks runs all SEC-HARDENING-*, SEC-CORS-01, SEC-OFFLINE-01, SEC-DEVMODE-01, and SEC-METRICS-01 checks. projectDir is the nSelf working directory (same value passed to DeepChecks).
func HasuraChecks ¶
func HasuraChecks(ctx context.Context, verbose bool) []CheckResult
HasuraChecks verifies /healthz 200 and metadata consistency.
func HostChecks ¶
func HostChecks(ctx context.Context, verbose bool) []CheckResult
HostChecks verifies disk, memory, CPU, time sync, kernel.
func IsolationChecks ¶ added in v1.4.15
func IsolationChecks(ctx context.Context, projectDir string) []CheckResult
IsolationChecks is the DeepChecks entry point for section `isolation`.
func LicenseChecks ¶
func LicenseChecks(ctx context.Context, projectDir string, verbose bool) []CheckResult
LicenseChecks verifies license is current and tier matches expected.
func MonitoringChecks ¶
func MonitoringChecks(ctx context.Context) []CheckResult
MonitoringChecks verifies monitoring stack health.
func NginxChecks ¶
func NginxChecks(ctx context.Context, projectDir string, verbose bool) []CheckResult
NginxChecks verifies the nginx config test and the served certificate expiry.
func PingChecks ¶
func PingChecks(ctx context.Context, verbose bool) []CheckResult
PingChecks verifies ping.nself.org reachable and license cache fresh.
func PluginHealthChecks ¶
func PluginHealthChecks(ctx context.Context, projectDir string, verbose bool) []CheckResult
PluginHealthChecks verifies every installed plugin's health endpoint, then appends the checks registered through RegisterExternal (P7-CI-53: the installed plugins' own doctors). The external checks run even when the container probe returns early (no Docker, no containers): a CLI plugin has no container.
func PluginMigrationChecks ¶ added in v1.4.13
func PluginMigrationChecks(ctx context.Context, pluginDir string) []CheckResult
PluginMigrationChecks is the DeepChecks entry point.
func PoolCapacityCheck ¶ added in v1.0.11
func PoolCapacityCheck(_ context.Context, pools []PoolConfig, postgresMaxConnections int) CheckResult
PoolCapacityCheck verifies that the total configured pgxpool connections across all active services do not exceed postgres_max_connections.
Returns a CheckResult with:
- Status "pass" when total_conns ≤ postgres_max_connections
- Status "warn" when total_conns > postgres_max_connections (not a hard block)
- Status "fail" when inputs are invalid (zero services, negative max)
This check fires in nself doctor --deep as PERF-POOL-01.
func PostgresChecks ¶
func PostgresChecks(ctx context.Context, projectDir string, verbose bool) []CheckResult
PostgresChecks verifies pg_isready, replication lag, longest query, dead tuples, vacuum.
func SSLChecks ¶
func SSLChecks(ctx context.Context, verbose bool) []CheckResult
SSLChecks verifies LE renewal cron, last renewal, OCSP stapling.
func SecurityChecks ¶
func SecurityChecks(ctx context.Context, projectDir string) []CheckResult
SecurityChecks runs security diagnostics.
func SystemChecks ¶
func SystemChecks(ctx context.Context, verbose bool) []CheckResult
SystemChecks runs system-level diagnostics: disk, memory, swap, load, clock sync, Docker, kernel.
func VectorSearchChecks ¶ added in v1.4.14
func VectorSearchChecks(ctx context.Context, projectDir string) []CheckResult
VectorSearchChecks is the DeepChecks entry point.
type ExternalFunc ¶ added in v1.4.15
type ExternalFunc func(ctx context.Context, projectDir string) []CheckResult
ExternalFunc is one provider of extra deep-doctor checks.
type PoolConfig ¶ added in v1.0.11
type PoolConfig struct {
ServiceName string
MaxConns int // per-service pgxpool MaxConns (0 = use pgxpoolDefaultMaxConns)
}
PoolConfig describes the pool sizing input for a single service. Each plugin or required service exposes one pool config.
func DefaultPoolConfigs ¶ added in v1.0.11
func DefaultPoolConfigs(services []string) []PoolConfig
DefaultPoolConfigs returns a pool config slice for the standard nSelf service set (4 required + up to 7 optional). Pass only the enabled services. Used by nself doctor --deep to compute the PERF-POOL-01 check.
type SocketInspector ¶ added in v1.4.15
type SocketInspector interface {
RunningContainers(ctx context.Context) ([]docker.ContainerInfo, error)
}
Source Files
¶
- backup_hint.go
- bundle_ledger_drift.go
- check_ci_token.go
- check_ci_vault_sync.go
- check_ssl_tracked.go
- deep.go
- deep_db.go
- deep_docker.go
- deep_docker_healthcheck.go
- deep_docker_socket.go
- deep_host.go
- deep_nginx.go
- deep_plugins.go
- dogfood_checks.go
- dogfood_deps_sport.go
- dogfood_headers.go
- dogfood_hexcolors.go
- entitlement_file.go
- entitlement_timer.go
- external.go
- hardening_check.go
- hardening_check_auth_net.go
- hardening_check_db.go
- hardening_check_helpers.go
- hardening_check_infra.go
- hardening_check_license_metrics.go
- hardening_check_nginx_fronted_dir.go
- hardening_check_nginx_zones.go
- hasura_introspection.go
- hasura_meta_reader.go
- hasura_remote_schema_orphans.go
- isolation_check.go
- isolation_meta.go
- isolation_rules.go
- jwt.go
- legal_coppa.go
- legal_gdpr_a9.go
- moderation_wired.go
- nself_audit_scan.go
- obs_scrape.go
- ops_drill.go
- paypal_csv_parity.go
- plugin_migrations.go
- pool_capacity.go
- project_name.go
- redact_audit.go
- rls_check.go
- rls_check_nsentry.go
- rls_hasura_filters.go
- sdk_version.go
- ssrf.go
- system.go
- system_backup.go
- system_monitoring.go
- system_security.go
- url_reserved.go
- vector_search.go