@schneiderjoseph/devia 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +149 -0
- package/CHANGELOG.md +78 -0
- package/GOVERNANCE.md +51 -0
- package/LEVELS.md +78 -0
- package/LICENSE +21 -0
- package/MATURITY.md +79 -0
- package/MEMORY.md +122 -0
- package/MIGRATION.md +62 -0
- package/PRINCIPLES.md +110 -0
- package/README.md +125 -0
- package/REFERENCES.md +30 -0
- package/VERSION +5 -0
- package/bin/devia.mjs +13 -0
- package/checklists/README.md +39 -0
- package/checklists/design/accessibility-review.md +11 -0
- package/checklists/design/design-to-code-review.md +10 -0
- package/checklists/design/responsive-review.md +7 -0
- package/checklists/design/ui-review.md +8 -0
- package/checklists/design/ux-review.md +10 -0
- package/checklists/engineering/accessibility.md +8 -0
- package/checklists/engineering/api.md +12 -0
- package/checklists/engineering/architecture.md +8 -0
- package/checklists/engineering/database.md +11 -0
- package/checklists/engineering/devops.md +9 -0
- package/checklists/engineering/disaster-recovery.md +9 -0
- package/checklists/engineering/frontend.md +9 -0
- package/checklists/engineering/incident.md +9 -0
- package/checklists/engineering/performance.md +7 -0
- package/checklists/engineering/production.md +26 -0
- package/checklists/engineering/release.md +17 -0
- package/checklists/engineering/security.md +33 -0
- package/checklists/engineering/testing.md +8 -0
- package/compliance/COVERAGE.md +46 -0
- package/compliance/REQUIREMENTS.md +8 -0
- package/compliance/TRACEABILITY.md +160 -0
- package/compliance/WAIVERS.md +13 -0
- package/package.json +74 -0
- package/rules/LIFECYCLE.md +16 -0
- package/rules/README.md +166 -0
- package/rules/accessibility/A11Y-001.md +42 -0
- package/rules/accessibility/A11Y-002.md +41 -0
- package/rules/accessibility/A11Y-003.md +40 -0
- package/rules/accessibility/A11Y-004.md +40 -0
- package/rules/accessibility/A11Y-005.md +39 -0
- package/rules/accessibility/A11Y-006.md +42 -0
- package/rules/accessibility/A11Y-007.md +39 -0
- package/rules/accessibility/A11Y-008.md +40 -0
- package/rules/accessibility/A11Y-009.md +41 -0
- package/rules/accessibility/A11Y-010.md +40 -0
- package/rules/accessibility/A11Y-011.md +39 -0
- package/rules/accessibility/A11Y-012.md +39 -0
- package/rules/agent/AGT-001.md +42 -0
- package/rules/agent/AGT-002.md +39 -0
- package/rules/agent/AGT-003.md +38 -0
- package/rules/agent/AGT-004.md +39 -0
- package/rules/agent/AGT-005.md +38 -0
- package/rules/agent/AGT-006.md +38 -0
- package/rules/agent/AGT-007.md +38 -0
- package/rules/agent/AGT-008.md +38 -0
- package/rules/agent/AGT-009.md +39 -0
- package/rules/agent/AGT-010.md +38 -0
- package/rules/agent/AGT-011.md +38 -0
- package/rules/ai/AI-001.md +44 -0
- package/rules/ai/AI-002.md +39 -0
- package/rules/ai/AI-003.md +40 -0
- package/rules/ai/AI-004.md +39 -0
- package/rules/ai/AI-005.md +38 -0
- package/rules/api/API-001.md +39 -0
- package/rules/api/API-002.md +39 -0
- package/rules/api/API-003.md +39 -0
- package/rules/api/API-004.md +38 -0
- package/rules/api/API-005.md +39 -0
- package/rules/api/API-006.md +40 -0
- package/rules/architecture/ARC-001.md +41 -0
- package/rules/architecture/ARC-002.md +43 -0
- package/rules/architecture/ARC-003.md +43 -0
- package/rules/architecture/ARC-004.md +40 -0
- package/rules/architecture/ARC-005.md +39 -0
- package/rules/architecture/ARC-006.md +39 -0
- package/rules/components/CMP-001.md +39 -0
- package/rules/components/CMP-002.md +38 -0
- package/rules/components/CMP-003.md +39 -0
- package/rules/components/CMP-004.md +40 -0
- package/rules/components/CMP-005.md +39 -0
- package/rules/content/CNT-001.md +39 -0
- package/rules/data-display/DATA-001.md +39 -0
- package/rules/data-display/DATA-002.md +39 -0
- package/rules/data-display/DATA-003.md +40 -0
- package/rules/data-display/DATA-004.md +40 -0
- package/rules/database/DB-001.md +43 -0
- package/rules/database/DB-002.md +38 -0
- package/rules/database/DB-003.md +40 -0
- package/rules/database/DB-004.md +44 -0
- package/rules/database/DB-005.md +39 -0
- package/rules/database/DB-006.md +38 -0
- package/rules/database/DB-007.md +40 -0
- package/rules/database/DB-008.md +40 -0
- package/rules/design-system/DS-001.md +39 -0
- package/rules/design-system/DS-002.md +40 -0
- package/rules/design-system/DS-003.md +38 -0
- package/rules/devops/OPS-001.md +43 -0
- package/rules/devops/OPS-002.md +39 -0
- package/rules/devops/OPS-003.md +38 -0
- package/rules/devops/OPS-004.md +40 -0
- package/rules/devops/OPS-005.md +43 -0
- package/rules/devops/OPS-006.md +38 -0
- package/rules/devops/OPS-007.md +40 -0
- package/rules/interaction/INT-001.md +39 -0
- package/rules/interaction/INT-002.md +39 -0
- package/rules/localization/I18N-001.md +38 -0
- package/rules/localization/I18N-002.md +40 -0
- package/rules/localization/I18N-003.md +39 -0
- package/rules/memory/MEM-001.md +44 -0
- package/rules/memory/MEM-002.md +39 -0
- package/rules/memory/MEM-003.md +38 -0
- package/rules/memory/MEM-004.md +38 -0
- package/rules/memory/MEM-005.md +38 -0
- package/rules/memory/MEM-006.md +38 -0
- package/rules/memory/MEM-007.md +38 -0
- package/rules/memory/MEM-008.md +38 -0
- package/rules/memory/MEM-009.md +39 -0
- package/rules/memory/MEM-010.md +38 -0
- package/rules/memory/MEM-011.md +38 -0
- package/rules/motion/MOT-001.md +38 -0
- package/rules/observability/OBS-001.md +40 -0
- package/rules/observability/OBS-002.md +40 -0
- package/rules/observability/OBS-003.md +38 -0
- package/rules/observability/OBS-004.md +38 -0
- package/rules/privacy/PRIV-001.md +38 -0
- package/rules/privacy/PRIV-002.md +44 -0
- package/rules/privacy/PRIV-003.md +40 -0
- package/rules/privacy/PRIV-004.md +41 -0
- package/rules/responsive/RWD-001.md +40 -0
- package/rules/responsive/RWD-002.md +39 -0
- package/rules/responsive/RWD-003.md +39 -0
- package/rules/security/SEC-001.md +44 -0
- package/rules/security/SEC-002.md +44 -0
- package/rules/security/SEC-003.md +41 -0
- package/rules/security/SEC-004.md +40 -0
- package/rules/security/SEC-005.md +42 -0
- package/rules/security/SEC-006.md +40 -0
- package/rules/security/SEC-007.md +44 -0
- package/rules/security/SEC-008.md +39 -0
- package/rules/security/SEC-009.md +40 -0
- package/rules/security/SEC-010.md +40 -0
- package/rules/security/SEC-011.md +40 -0
- package/rules/security/SEC-012.md +40 -0
- package/rules/states/STATE-001.md +38 -0
- package/rules/states/STATE-002.md +39 -0
- package/rules/states/STATE-003.md +39 -0
- package/rules/states/STATE-004.md +38 -0
- package/rules/testing/TST-001.md +39 -0
- package/rules/testing/TST-002.md +39 -0
- package/rules/testing/TST-003.md +39 -0
- package/rules/testing/TST-004.md +38 -0
- package/rules/testing/TST-005.md +40 -0
- package/rules/testing/TST-006.md +39 -0
- package/rules/ui/UI-001.md +40 -0
- package/rules/ui/UI-002.md +38 -0
- package/rules/ui/UI-003.md +41 -0
- package/rules/ui/UI-004.md +41 -0
- package/rules/ui/UI-005.md +41 -0
- package/rules/ui/UI-006.md +40 -0
- package/rules/ui/UI-007.md +41 -0
- package/rules/ux/UX-001.md +41 -0
- package/rules/ux/UX-002.md +41 -0
- package/rules/ux/UX-003.md +39 -0
- package/rules/ux/UX-004.md +39 -0
- package/rules/ux/UX-005.md +40 -0
- package/rules/ux/UX-006.md +40 -0
- package/rules/ux/UX-007.md +44 -0
- package/rules/ux/UX-008.md +41 -0
- package/rules/ux/UX-009.md +39 -0
- package/rules/ux/UX-010.md +40 -0
- package/rules/ux/UX-011.md +40 -0
- package/rules/ux/UX-012.md +40 -0
- package/rules/ux/UX-013.md +39 -0
- package/schema/README.md +19 -0
- package/schema/checklist.schema.json +34 -0
- package/schema/component.schema.json +37 -0
- package/schema/project-config.schema.json +70 -0
- package/schema/rule.schema.json +104 -0
- package/schema/token.schema.json +15 -0
- package/schema/waiver.schema.json +33 -0
- package/scripts/build-index.mjs +178 -0
- package/scripts/validate-links.mjs +43 -0
- package/scripts/validate-rules.mjs +42 -0
- package/skills/devia/SKILL.md +114 -0
- package/src/cli.mjs +107 -0
- package/src/commands/check.mjs +483 -0
- package/src/commands/doctor.mjs +139 -0
- package/src/commands/init.mjs +186 -0
- package/src/commands/registry.mjs +154 -0
- package/src/commands/rules.mjs +101 -0
- package/src/commands/skills.mjs +97 -0
- package/src/commands/sync.mjs +83 -0
- package/src/commands/validate.mjs +194 -0
- package/src/lib/fs.mjs +89 -0
- package/src/lib/git.mjs +31 -0
- package/src/lib/rules.mjs +85 -0
- package/src/lib/ui.mjs +52 -0
- package/src/lib/vendor.mjs +74 -0
- package/src/lib/version.mjs +19 -0
- package/src/lib/yaml.mjs +152 -0
- package/standard/README.md +31 -0
- package/standard/design/README.md +51 -0
- package/standard/design/REFERENCES.md +39 -0
- package/standard/design/accessibility/aria.md +7 -0
- package/standard/design/accessibility/contrast.md +6 -0
- package/standard/design/accessibility/focus.md +6 -0
- package/standard/design/accessibility/forms.md +3 -0
- package/standard/design/accessibility/keyboard.md +6 -0
- package/standard/design/accessibility/reduced-motion.md +3 -0
- package/standard/design/accessibility/reflow.md +3 -0
- package/standard/design/accessibility/screen-readers.md +3 -0
- package/standard/design/accessibility/target-size.md +3 -0
- package/standard/design/accessibility/testing.md +3 -0
- package/standard/design/accessibility/wcag-2.2.md +16 -0
- package/standard/design/accessibility/zoom.md +3 -0
- package/standard/design/ai/ai-design-rules.md +8 -0
- package/standard/design/ai/anti-patterns.md +1 -0
- package/standard/design/ai/compliance-format.md +22 -0
- package/standard/design/ai/design-review.md +10 -0
- package/standard/design/ai/evals/README.md +1 -0
- package/standard/design/ai/instructions.md +7 -0
- package/standard/design/ai/prompts/accessibility-review.md +5 -0
- package/standard/design/ai/prompts/design-system-review.md +5 -0
- package/standard/design/ai/prompts/ui-review.md +5 -0
- package/standard/design/ai/prompts/ux-review.md +5 -0
- package/standard/design/ai/review-protocol.md +11 -0
- package/standard/design/anti-patterns/accessibility.md +7 -0
- package/standard/design/anti-patterns/ai-generated.md +6 -0
- package/standard/design/anti-patterns/dashboards.md +5 -0
- package/standard/design/anti-patterns/forms.md +5 -0
- package/standard/design/anti-patterns/responsive.md +5 -0
- package/standard/design/anti-patterns/ui.md +6 -0
- package/standard/design/anti-patterns/ux.md +5 -0
- package/standard/design/components/buttons.md +6 -0
- package/standard/design/components/dialogs.md +5 -0
- package/standard/design/components/feedback.md +3 -0
- package/standard/design/components/forms.md +3 -0
- package/standard/design/components/navigation.md +3 -0
- package/standard/design/components/tables.md +6 -0
- package/standard/design/content/error-messages.md +4 -0
- package/standard/design/content/ux-writing.md +5 -0
- package/standard/design/data-display/README.md +5 -0
- package/standard/design/data-display/currency.md +3 -0
- package/standard/design/data-display/dates.md +3 -0
- package/standard/design/data-display/density.md +3 -0
- package/standard/design/data-display/filtering.md +3 -0
- package/standard/design/data-display/localization.md +3 -0
- package/standard/design/data-display/numbers.md +3 -0
- package/standard/design/data-display/pagination.md +3 -0
- package/standard/design/data-display/percentages.md +3 -0
- package/standard/design/data-display/sorting.md +3 -0
- package/standard/design/data-display/tables.md +3 -0
- package/standard/design/data-display/time.md +3 -0
- package/standard/design/decisions/ADR-001-token-naming.md +13 -0
- package/standard/design/decisions/ADR-002-radius-scale.md +9 -0
- package/standard/design/decisions/ADR-003-color-system.md +9 -0
- package/standard/design/decisions/ADR-004-component-versioning.md +9 -0
- package/standard/design/decisions/README.md +3 -0
- package/standard/design/design-system/components.md +9 -0
- package/standard/design/design-system/naming.md +19 -0
- package/standard/design/design-system/tokens.md +7 -0
- package/standard/design/design-system/variants.md +5 -0
- package/standard/design/design-system/versioning.md +5 -0
- package/standard/design/health/coverage.md +1 -0
- package/standard/design/health/dashboard.md +14 -0
- package/standard/design/health/maturity-model.md +9 -0
- package/standard/design/health/score.md +14 -0
- package/standard/design/interaction/README.md +10 -0
- package/standard/design/interaction/keyboard.md +3 -0
- package/standard/design/interaction/mouse.md +2 -0
- package/standard/design/interaction/pen.md +1 -0
- package/standard/design/interaction/touch.md +3 -0
- package/standard/design/interaction/touchscreen.md +6 -0
- package/standard/design/interaction/voice.md +2 -0
- package/standard/design/localization/README.md +5 -0
- package/standard/design/localization/currency.md +3 -0
- package/standard/design/localization/date-time.md +3 -0
- package/standard/design/localization/i18n.md +3 -0
- package/standard/design/localization/locale-testing.md +3 -0
- package/standard/design/localization/number-formatting.md +3 -0
- package/standard/design/localization/pluralization.md +3 -0
- package/standard/design/localization/rtl.md +3 -0
- package/standard/design/localization/text-expansion.md +3 -0
- package/standard/design/motion/animation.md +6 -0
- package/standard/design/penpot/WORKFLOW.md +27 -0
- package/standard/design/platforms/README.md +12 -0
- package/standard/design/platforms/desktop/README.md +5 -0
- package/standard/design/platforms/mobile/android.md +5 -0
- package/standard/design/platforms/mobile/ios.md +5 -0
- package/standard/design/platforms/tablet/README.md +5 -0
- package/standard/design/platforms/web/README.md +1 -0
- package/standard/design/principles/design-principles.md +9 -0
- package/standard/design/principles/ui-principles.md +7 -0
- package/standard/design/principles/ux-principles.md +14 -0
- package/standard/design/references/atlassian.md +3 -0
- package/standard/design/references/carbon.md +3 -0
- package/standard/design/references/figma-sds.md +5 -0
- package/standard/design/references/govuk.md +3 -0
- package/standard/design/references/material.md +3 -0
- package/standard/design/references/nng.md +3 -0
- package/standard/design/references/openui.md +3 -0
- package/standard/design/references/primer.md +5 -0
- package/standard/design/references/storybook.md +3 -0
- package/standard/design/references/uswds.md +3 -0
- package/standard/design/references/w3c.md +3 -0
- package/standard/design/responsive/desktop.md +4 -0
- package/standard/design/responsive/mobile.md +6 -0
- package/standard/design/responsive/tablet.md +3 -0
- package/standard/design/states/async.md +3 -0
- package/standard/design/states/conflict.md +3 -0
- package/standard/design/states/empty.md +3 -0
- package/standard/design/states/error.md +3 -0
- package/standard/design/states/interaction.md +5 -0
- package/standard/design/states/loading.md +3 -0
- package/standard/design/states/offline.md +3 -0
- package/standard/design/states/optimistic.md +3 -0
- package/standard/design/states/partial.md +3 -0
- package/standard/design/states/permission-denied.md +3 -0
- package/standard/design/states/rate-limited.md +3 -0
- package/standard/design/states/read-only.md +3 -0
- package/standard/design/states/retry.md +3 -0
- package/standard/design/states/skeleton.md +3 -0
- package/standard/design/states/stale.md +3 -0
- package/standard/design/states/success.md +3 -0
- package/standard/design/states/timeout.md +3 -0
- package/standard/design/states/unsaved-changes.md +3 -0
- package/standard/design/ui/color.md +6 -0
- package/standard/design/ui/grids.md +5 -0
- package/standard/design/ui/icons.md +5 -0
- package/standard/design/ui/imagery.md +5 -0
- package/standard/design/ui/layout.md +5 -0
- package/standard/design/ui/spacing.md +5 -0
- package/standard/design/ui/typography.md +6 -0
- package/standard/design/ui/visual-design.md +7 -0
- package/standard/design/ux/cognitive-load.md +5 -0
- package/standard/design/ux/errors.md +6 -0
- package/standard/design/ux/feedback.md +5 -0
- package/standard/design/ux/forms.md +7 -0
- package/standard/design/ux/heuristics.md +14 -0
- package/standard/design/ux/information-architecture.md +6 -0
- package/standard/design/ux/navigation.md +6 -0
- package/standard/design/ux/usability.md +6 -0
- package/standard/engineering/README.md +29 -0
- package/standard/engineering/REFERENCES.md +42 -0
- package/standard/engineering/ai/AI_SECURITY.md +15 -0
- package/standard/engineering/ai/PROMPT_SECURITY.md +6 -0
- package/standard/engineering/architecture/ADR.md +11 -0
- package/standard/engineering/architecture/ARCHITECTURE.md +25 -0
- package/standard/engineering/architecture/PRINCIPLES.md +17 -0
- package/standard/engineering/architecture/THREAT_MODEL.md +14 -0
- package/standard/engineering/backend/API.md +29 -0
- package/standard/engineering/backend/BACKGROUND_JOBS.md +12 -0
- package/standard/engineering/backend/ERROR_HANDLING.md +26 -0
- package/standard/engineering/backend/LOGGING.md +12 -0
- package/standard/engineering/compliance/DATA_RETENTION.md +10 -0
- package/standard/engineering/compliance/PRIVACY.md +11 -0
- package/standard/engineering/database/BACKUPS.md +19 -0
- package/standard/engineering/database/DATABASE.md +30 -0
- package/standard/engineering/database/MIGRATIONS.md +12 -0
- package/standard/engineering/devops/BRANCH_PROTECTION.md +17 -0
- package/standard/engineering/devops/CI_CD.md +48 -0
- package/standard/engineering/devops/DEPLOYMENT.md +12 -0
- package/standard/engineering/devops/DOCKER.md +9 -0
- package/standard/engineering/devops/ENVIRONMENTS.md +12 -0
- package/standard/engineering/devops/RELEASE.md +6 -0
- package/standard/engineering/devops/ROLLBACK.md +9 -0
- package/standard/engineering/frontend/ACCESSIBILITY.md +16 -0
- package/standard/engineering/frontend/DESIGN_SYSTEM.md +10 -0
- package/standard/engineering/frontend/FRONTEND.md +17 -0
- package/standard/engineering/frontend/UX.md +15 -0
- package/standard/engineering/observability/ALERTING.md +11 -0
- package/standard/engineering/observability/INCIDENTS.md +10 -0
- package/standard/engineering/observability/MONITORING.md +17 -0
- package/standard/engineering/payments/PAYMENTS.md +15 -0
- package/standard/engineering/performance/PERFORMANCE.md +19 -0
- package/standard/engineering/security/API_SECURITY.md +22 -0
- package/standard/engineering/security/ASVS_5.0/V10_MALICIOUS_CODE.md +31 -0
- package/standard/engineering/security/ASVS_5.0/V11_BUSINESS_LOGIC.md +31 -0
- package/standard/engineering/security/ASVS_5.0/V12_FILES.md +31 -0
- package/standard/engineering/security/ASVS_5.0/V13_API.md +31 -0
- package/standard/engineering/security/ASVS_5.0/V14_CONFIGURATION.md +31 -0
- package/standard/engineering/security/ASVS_5.0/V1_ARCHITECTURE.md +31 -0
- package/standard/engineering/security/ASVS_5.0/V2_AUTHENTICATION.md +31 -0
- package/standard/engineering/security/ASVS_5.0/V3_SESSION.md +31 -0
- package/standard/engineering/security/ASVS_5.0/V4_ACCESS_CONTROL.md +31 -0
- package/standard/engineering/security/ASVS_5.0/V5_VALIDATION.md +31 -0
- package/standard/engineering/security/ASVS_5.0/V6_CRYPTOGRAPHY.md +31 -0
- package/standard/engineering/security/ASVS_5.0/V7_ERROR_HANDLING.md +31 -0
- package/standard/engineering/security/ASVS_5.0/V8_DATA_PROTECTION.md +31 -0
- package/standard/engineering/security/ASVS_5.0/V9_COMMUNICATION.md +31 -0
- package/standard/engineering/security/ASVS_REGISTRY.md +31 -0
- package/standard/engineering/security/AUTHENTICATION.md +28 -0
- package/standard/engineering/security/AUTHORIZATION.md +27 -0
- package/standard/engineering/security/DATA_SECURITY.md +14 -0
- package/standard/engineering/security/OWASP_ASVS.md +31 -0
- package/standard/engineering/security/SECRETS.md +28 -0
- package/standard/engineering/security/SECURITY.md +28 -0
- package/standard/engineering/testing/TESTING.md +27 -0
- package/templates/agents/AGENTS.md +34 -0
- package/templates/agents/CLAUDE.md +33 -0
- package/templates/agents/copilot-instructions.md +15 -0
- package/templates/agents/cursor.mdc +27 -0
- package/templates/agents/windsurfrules.md +17 -0
- package/templates/docs/ADR.md +16 -0
- package/templates/docs/FEATURE.md +19 -0
- package/templates/docs/SECURITY_REPORT.md +15 -0
- package/templates/docs/accessibility-review.md +9 -0
- package/templates/docs/component.md +9 -0
- package/templates/docs/decision-record.md +9 -0
- package/templates/docs/design-review.md +9 -0
- package/templates/docs/exception.md +9 -0
- package/templates/docs/page.md +9 -0
- package/templates/docs/pattern.md +9 -0
- package/templates/docs/user-flow.md +9 -0
- package/templates/github/workflows/app-ci.yml +91 -0
- package/templates/project/00_OVERVIEW.md +51 -0
- package/templates/project/01_ARCHITECTURE.md +37 -0
- package/templates/project/02_SURFACES.md +30 -0
- package/templates/project/03_DATA_MODEL.md +31 -0
- package/templates/project/04_PERMISSIONS.md +32 -0
- package/templates/project/05_FLOWS.md +20 -0
- package/templates/project/06_INTEGRATIONS.md +21 -0
- package/templates/project/07_DESIGN.md +33 -0
- package/templates/project/10_NEVER_ALWAYS.md +26 -0
- package/templates/project/11_GAPS.md +18 -0
- package/templates/project/12_DEBT.md +19 -0
- package/templates/project/13_RECIPES.md +35 -0
- package/templates/project/14_INDEX.md +50 -0
- package/templates/project/AGENTS.md +51 -0
- package/templates/project/README.md +49 -0
- package/templates/project/impact-map.yaml +41 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: PRIV-002
|
|
3
|
+
title: Retention and deletion are defined and implemented
|
|
4
|
+
severity: MUST
|
|
5
|
+
status: active
|
|
6
|
+
domain: privacy
|
|
7
|
+
priority: P1
|
|
8
|
+
source:
|
|
9
|
+
- GDPR principles
|
|
10
|
+
applies_to:
|
|
11
|
+
- database
|
|
12
|
+
- service
|
|
13
|
+
success_criteria:
|
|
14
|
+
[]
|
|
15
|
+
requirement: >
|
|
16
|
+
Every category of personal data MUST have a retention period and a mechanism that actually enforces it, including backups and logs.
|
|
17
|
+
validation:
|
|
18
|
+
automated: false
|
|
19
|
+
manual: true
|
|
20
|
+
exceptions: documented-only
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# PRIV-002 — Retention and deletion are defined and implemented
|
|
24
|
+
|
|
25
|
+
**Requirement:** Every category of personal data MUST have a retention period and a mechanism that actually enforces it, including backups and logs.
|
|
26
|
+
|
|
27
|
+
**Bad:** A retention policy in a document, with data kept forever in practice.
|
|
28
|
+
|
|
29
|
+
**Good:** A scheduled job that removes or anonymises expired data, with the policy recorded next to it.
|
|
30
|
+
|
|
31
|
+
## Validation
|
|
32
|
+
|
|
33
|
+
- Retention documented per category
|
|
34
|
+
- The job exists and has run
|
|
35
|
+
|
|
36
|
+
## Lifecycle
|
|
37
|
+
|
|
38
|
+
- Status: `active`
|
|
39
|
+
- Priority: `P1`
|
|
40
|
+
- Exceptions: `documented-only`
|
|
41
|
+
|
|
42
|
+
## See also
|
|
43
|
+
|
|
44
|
+
- [DATA_RETENTION.md](../../standard/engineering/compliance/DATA_RETENTION.md)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: PRIV-003
|
|
3
|
+
title: Users can obtain and erase their data
|
|
4
|
+
severity: MUST
|
|
5
|
+
status: active
|
|
6
|
+
domain: privacy
|
|
7
|
+
priority: P1
|
|
8
|
+
source:
|
|
9
|
+
- GDPR principles
|
|
10
|
+
applies_to:
|
|
11
|
+
- api
|
|
12
|
+
- service
|
|
13
|
+
success_criteria:
|
|
14
|
+
[]
|
|
15
|
+
requirement: >
|
|
16
|
+
Where the product holds personal data, an export path and an erasure path MUST exist, MUST be authenticated, and MUST state what erasure cannot remove and why.
|
|
17
|
+
validation:
|
|
18
|
+
automated: false
|
|
19
|
+
manual: true
|
|
20
|
+
exceptions: documented-only
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# PRIV-003 — Users can obtain and erase their data
|
|
24
|
+
|
|
25
|
+
**Requirement:** Where the product holds personal data, an export path and an erasure path MUST exist, MUST be authenticated, and MUST state what erasure cannot remove and why.
|
|
26
|
+
|
|
27
|
+
**Bad:** Support deletes rows by hand on request, differently each time.
|
|
28
|
+
|
|
29
|
+
**Good:** A tested export and an erasure flow that names its exceptions (legal retention, audit trail).
|
|
30
|
+
|
|
31
|
+
## Validation
|
|
32
|
+
|
|
33
|
+
- Both flows exist and are tested
|
|
34
|
+
- Exceptions documented
|
|
35
|
+
|
|
36
|
+
## Lifecycle
|
|
37
|
+
|
|
38
|
+
- Status: `active`
|
|
39
|
+
- Priority: `P1`
|
|
40
|
+
- Exceptions: `documented-only`
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: PRIV-004
|
|
3
|
+
title: Personal data stays out of logs, analytics and prompts
|
|
4
|
+
severity: MUST
|
|
5
|
+
status: active
|
|
6
|
+
domain: privacy
|
|
7
|
+
priority: P1
|
|
8
|
+
source:
|
|
9
|
+
- GDPR principles
|
|
10
|
+
applies_to:
|
|
11
|
+
- service
|
|
12
|
+
- web
|
|
13
|
+
- ai
|
|
14
|
+
success_criteria:
|
|
15
|
+
[]
|
|
16
|
+
requirement: >
|
|
17
|
+
Personal data MUST NOT be sent to logs, analytics, third-party tools or model providers unless that transfer is a recorded decision with a lawful basis and a data agreement.
|
|
18
|
+
validation:
|
|
19
|
+
automated: true
|
|
20
|
+
manual: true
|
|
21
|
+
exceptions: documented-only
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# PRIV-004 — Personal data stays out of logs, analytics and prompts
|
|
25
|
+
|
|
26
|
+
**Requirement:** Personal data MUST NOT be sent to logs, analytics, third-party tools or model providers unless that transfer is a recorded decision with a lawful basis and a data agreement.
|
|
27
|
+
|
|
28
|
+
**Bad:** Full customer records pasted into a model prompt for summarisation.
|
|
29
|
+
|
|
30
|
+
**Good:** Identifiers are pseudonymised; the transfer, if needed, is recorded and minimised.
|
|
31
|
+
|
|
32
|
+
## Validation
|
|
33
|
+
|
|
34
|
+
- Grep the diff for personal fields crossing a boundary
|
|
35
|
+
- The transfer is recorded
|
|
36
|
+
|
|
37
|
+
## Lifecycle
|
|
38
|
+
|
|
39
|
+
- Status: `active`
|
|
40
|
+
- Priority: `P1`
|
|
41
|
+
- Exceptions: `documented-only`
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: RWD-001
|
|
3
|
+
title: Touch targets adequate
|
|
4
|
+
severity: MUST
|
|
5
|
+
status: active
|
|
6
|
+
priority: P1
|
|
7
|
+
domain: responsive
|
|
8
|
+
source:
|
|
9
|
+
- WCAG-2.2
|
|
10
|
+
applies_to:
|
|
11
|
+
- touch
|
|
12
|
+
- mobile
|
|
13
|
+
- tablet
|
|
14
|
+
success_criteria:
|
|
15
|
+
[]
|
|
16
|
+
requirement: >
|
|
17
|
+
Primary touch targets MUST be comfortably tappable; meet A11Y-010 at minimum.
|
|
18
|
+
validation:
|
|
19
|
+
automated: false
|
|
20
|
+
manual: true
|
|
21
|
+
exceptions: documented-only
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# RWD-001 — Touch targets adequate
|
|
25
|
+
|
|
26
|
+
**Requirement:** Primary touch targets MUST be comfortably tappable; meet A11Y-010 at minimum.
|
|
27
|
+
|
|
28
|
+
**Bad:** Dense icon row unusable on phone.
|
|
29
|
+
|
|
30
|
+
**Good:** 44×44 primary actions; spacing between targets.
|
|
31
|
+
|
|
32
|
+
## Validation
|
|
33
|
+
|
|
34
|
+
- Design or engineering review
|
|
35
|
+
|
|
36
|
+
## Lifecycle
|
|
37
|
+
|
|
38
|
+
- Status: `active`
|
|
39
|
+
- Priority: `P1`
|
|
40
|
+
- Exceptions: `documented-only`
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: RWD-002
|
|
3
|
+
title: Core flows at 320px
|
|
4
|
+
severity: MUST
|
|
5
|
+
status: active
|
|
6
|
+
priority: P0
|
|
7
|
+
domain: responsive
|
|
8
|
+
source:
|
|
9
|
+
- WCAG-2.2
|
|
10
|
+
applies_to:
|
|
11
|
+
- mobile
|
|
12
|
+
- web
|
|
13
|
+
success_criteria:
|
|
14
|
+
- "1.4.10"
|
|
15
|
+
requirement: >
|
|
16
|
+
Core flows MUST be usable without horizontal page scrolling at 320 CSS px (except intentional overflow with accessible alternative).
|
|
17
|
+
validation:
|
|
18
|
+
automated: false
|
|
19
|
+
manual: true
|
|
20
|
+
exceptions: documented-only
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# RWD-002 — Core flows at 320px
|
|
24
|
+
|
|
25
|
+
**Requirement:** Core flows MUST be usable without horizontal page scrolling at 320 CSS px (except intentional overflow with accessible alternative).
|
|
26
|
+
|
|
27
|
+
**Bad:** Login requires horizontal scroll.
|
|
28
|
+
|
|
29
|
+
**Good:** Stacked form layout.
|
|
30
|
+
|
|
31
|
+
## Validation
|
|
32
|
+
|
|
33
|
+
- Design or engineering review
|
|
34
|
+
|
|
35
|
+
## Lifecycle
|
|
36
|
+
|
|
37
|
+
- Status: `active`
|
|
38
|
+
- Priority: `P0`
|
|
39
|
+
- Exceptions: `documented-only`
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: RWD-003
|
|
3
|
+
title: Hover not the only path
|
|
4
|
+
severity: MUST
|
|
5
|
+
status: active
|
|
6
|
+
priority: P0
|
|
7
|
+
domain: responsive
|
|
8
|
+
source:
|
|
9
|
+
- WCAG-2.2
|
|
10
|
+
applies_to:
|
|
11
|
+
- desktop
|
|
12
|
+
- touch
|
|
13
|
+
success_criteria:
|
|
14
|
+
- "2.5.1"
|
|
15
|
+
requirement: >
|
|
16
|
+
Functionality revealed only on hover MUST have a keyboard/touch equivalent.
|
|
17
|
+
validation:
|
|
18
|
+
automated: false
|
|
19
|
+
manual: true
|
|
20
|
+
exceptions: documented-only
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# RWD-003 — Hover not the only path
|
|
24
|
+
|
|
25
|
+
**Requirement:** Functionality revealed only on hover MUST have a keyboard/touch equivalent.
|
|
26
|
+
|
|
27
|
+
**Bad:** Delete only appears on row hover.
|
|
28
|
+
|
|
29
|
+
**Good:** Always-visible overflow menu or focus-revealed actions.
|
|
30
|
+
|
|
31
|
+
## Validation
|
|
32
|
+
|
|
33
|
+
- Design or engineering review
|
|
34
|
+
|
|
35
|
+
## Lifecycle
|
|
36
|
+
|
|
37
|
+
- Status: `active`
|
|
38
|
+
- Priority: `P0`
|
|
39
|
+
- Exceptions: `documented-only`
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: SEC-001
|
|
3
|
+
title: Server-side authorization on every sensitive operation
|
|
4
|
+
severity: MUST
|
|
5
|
+
status: active
|
|
6
|
+
domain: security
|
|
7
|
+
priority: P0
|
|
8
|
+
source:
|
|
9
|
+
- OWASP ASVS 5.0 V4
|
|
10
|
+
applies_to:
|
|
11
|
+
- api
|
|
12
|
+
- service
|
|
13
|
+
success_criteria:
|
|
14
|
+
[]
|
|
15
|
+
requirement: >
|
|
16
|
+
Every operation that reads or changes data belonging to a user, tenant or role MUST verify authorization on the server, on every request, from the session identity — never from a client-supplied identifier.
|
|
17
|
+
validation:
|
|
18
|
+
automated: false
|
|
19
|
+
manual: true
|
|
20
|
+
exceptions: none
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# SEC-001 — Server-side authorization on every sensitive operation
|
|
24
|
+
|
|
25
|
+
**Requirement:** Every operation that reads or changes data belonging to a user, tenant or role MUST verify authorization on the server, on every request, from the session identity — never from a client-supplied identifier.
|
|
26
|
+
|
|
27
|
+
**Bad:** The endpoint trusts `userId` from the request body, or the UI simply hides the button.
|
|
28
|
+
|
|
29
|
+
**Good:** The handler derives the actor from the session and checks the actor's right to that resource before doing anything.
|
|
30
|
+
|
|
31
|
+
## Validation
|
|
32
|
+
|
|
33
|
+
- Test: actor A cannot reach actor B's resource
|
|
34
|
+
- Test: role without permission gets 403, not 200
|
|
35
|
+
|
|
36
|
+
## Lifecycle
|
|
37
|
+
|
|
38
|
+
- Status: `active`
|
|
39
|
+
- Priority: `P0`
|
|
40
|
+
- Exceptions: `none`
|
|
41
|
+
|
|
42
|
+
## See also
|
|
43
|
+
|
|
44
|
+
- [AUTHORIZATION.md](../../standard/engineering/security/AUTHORIZATION.md)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: SEC-002
|
|
3
|
+
title: No secrets in source, config, logs or client bundles
|
|
4
|
+
severity: MUST NOT
|
|
5
|
+
status: active
|
|
6
|
+
domain: security
|
|
7
|
+
priority: P0
|
|
8
|
+
source:
|
|
9
|
+
- OWASP ASVS 5.0 V14
|
|
10
|
+
applies_to:
|
|
11
|
+
- repository
|
|
12
|
+
success_criteria:
|
|
13
|
+
[]
|
|
14
|
+
requirement: >
|
|
15
|
+
Credentials, API keys, tokens and private keys MUST NOT be committed, embedded in a client bundle, printed in logs, or pasted into an issue, prompt or transcript.
|
|
16
|
+
validation:
|
|
17
|
+
automated: true
|
|
18
|
+
manual: true
|
|
19
|
+
exceptions: none
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# SEC-002 — No secrets in source, config, logs or client bundles
|
|
23
|
+
|
|
24
|
+
**Requirement:** Credentials, API keys, tokens and private keys MUST NOT be committed, embedded in a client bundle, printed in logs, or pasted into an issue, prompt or transcript.
|
|
25
|
+
|
|
26
|
+
**Bad:** `STRIPE_SECRET_KEY` in a `.env` that is committed, or echoed by a debug log line.
|
|
27
|
+
|
|
28
|
+
**Good:** Secrets come from the platform secret store at runtime; `.env.example` holds names, never values.
|
|
29
|
+
|
|
30
|
+
## Validation
|
|
31
|
+
|
|
32
|
+
- Secret scan in CI
|
|
33
|
+
- Grep the client bundle for key patterns
|
|
34
|
+
- Rotate any secret that ever touched the repository
|
|
35
|
+
|
|
36
|
+
## Lifecycle
|
|
37
|
+
|
|
38
|
+
- Status: `active`
|
|
39
|
+
- Priority: `P0`
|
|
40
|
+
- Exceptions: `none`
|
|
41
|
+
|
|
42
|
+
## See also
|
|
43
|
+
|
|
44
|
+
- [SECRETS.md](../../standard/engineering/security/SECRETS.md)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: SEC-003
|
|
3
|
+
title: External input is validated before use
|
|
4
|
+
severity: MUST
|
|
5
|
+
status: active
|
|
6
|
+
domain: security
|
|
7
|
+
priority: P0
|
|
8
|
+
source:
|
|
9
|
+
- OWASP ASVS 5.0 V5
|
|
10
|
+
applies_to:
|
|
11
|
+
- api
|
|
12
|
+
- service
|
|
13
|
+
- web
|
|
14
|
+
success_criteria:
|
|
15
|
+
[]
|
|
16
|
+
requirement: >
|
|
17
|
+
Every input crossing a trust boundary — request bodies, query strings, headers, webhooks, uploads, third-party responses, model output — MUST be validated against an explicit schema and rejected when it does not match.
|
|
18
|
+
validation:
|
|
19
|
+
automated: true
|
|
20
|
+
manual: true
|
|
21
|
+
exceptions: none
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# SEC-003 — External input is validated before use
|
|
25
|
+
|
|
26
|
+
**Requirement:** Every input crossing a trust boundary — request bodies, query strings, headers, webhooks, uploads, third-party responses, model output — MUST be validated against an explicit schema and rejected when it does not match.
|
|
27
|
+
|
|
28
|
+
**Bad:** `JSON.parse(body)` is passed straight to an ORM write.
|
|
29
|
+
|
|
30
|
+
**Good:** The body is parsed into a declared schema; unknown fields are rejected; types and ranges are enforced.
|
|
31
|
+
|
|
32
|
+
## Validation
|
|
33
|
+
|
|
34
|
+
- Every new endpoint has a schema
|
|
35
|
+
- Test: malformed and oversized input is rejected
|
|
36
|
+
|
|
37
|
+
## Lifecycle
|
|
38
|
+
|
|
39
|
+
- Status: `active`
|
|
40
|
+
- Priority: `P0`
|
|
41
|
+
- Exceptions: `none`
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: SEC-004
|
|
3
|
+
title: Internal error detail never reaches a production client
|
|
4
|
+
severity: MUST
|
|
5
|
+
status: active
|
|
6
|
+
domain: security
|
|
7
|
+
priority: P0
|
|
8
|
+
source:
|
|
9
|
+
- OWASP ASVS 5.0 V7
|
|
10
|
+
applies_to:
|
|
11
|
+
- api
|
|
12
|
+
- web
|
|
13
|
+
success_criteria:
|
|
14
|
+
[]
|
|
15
|
+
requirement: >
|
|
16
|
+
Stack traces, SQL text, file paths, internal hostnames and framework diagnostics MUST NOT be returned to clients in production. The client gets a stable code and a human-readable message; the detail goes to the log.
|
|
17
|
+
validation:
|
|
18
|
+
automated: true
|
|
19
|
+
manual: true
|
|
20
|
+
exceptions: none
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# SEC-004 — Internal error detail never reaches a production client
|
|
24
|
+
|
|
25
|
+
**Requirement:** Stack traces, SQL text, file paths, internal hostnames and framework diagnostics MUST NOT be returned to clients in production. The client gets a stable code and a human-readable message; the detail goes to the log.
|
|
26
|
+
|
|
27
|
+
**Bad:** A 500 response containing the query and the table name.
|
|
28
|
+
|
|
29
|
+
**Good:** `{ "error": "payment_failed", "message": "We could not process this payment." }` plus a correlated log entry.
|
|
30
|
+
|
|
31
|
+
## Validation
|
|
32
|
+
|
|
33
|
+
- Test an error path against the production configuration
|
|
34
|
+
- Confirm the error handler is the last middleware
|
|
35
|
+
|
|
36
|
+
## Lifecycle
|
|
37
|
+
|
|
38
|
+
- Status: `active`
|
|
39
|
+
- Priority: `P0`
|
|
40
|
+
- Exceptions: `none`
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: SEC-005
|
|
3
|
+
title: Tenant and user isolation is enforced and tested
|
|
4
|
+
severity: MUST
|
|
5
|
+
status: active
|
|
6
|
+
domain: security
|
|
7
|
+
priority: P0
|
|
8
|
+
source:
|
|
9
|
+
- OWASP ASVS 5.0 V4
|
|
10
|
+
applies_to:
|
|
11
|
+
- api
|
|
12
|
+
- service
|
|
13
|
+
- database
|
|
14
|
+
success_criteria:
|
|
15
|
+
[]
|
|
16
|
+
requirement: >
|
|
17
|
+
Every query touching user- or tenant-scoped data MUST be constrained by the actor's scope, and that constraint MUST be covered by a test that fails when the constraint is removed.
|
|
18
|
+
validation:
|
|
19
|
+
automated: false
|
|
20
|
+
manual: true
|
|
21
|
+
exceptions: none
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# SEC-005 — Tenant and user isolation is enforced and tested
|
|
25
|
+
|
|
26
|
+
**Requirement:** Every query touching user- or tenant-scoped data MUST be constrained by the actor's scope, and that constraint MUST be covered by a test that fails when the constraint is removed.
|
|
27
|
+
|
|
28
|
+
**Bad:** A list endpoint filters by tenant in the UI only.
|
|
29
|
+
|
|
30
|
+
**Good:** The query carries the tenant predicate (or a row-level policy does), and a test proves cross-tenant reads return nothing.
|
|
31
|
+
|
|
32
|
+
## Validation
|
|
33
|
+
|
|
34
|
+
- Cross-tenant read test
|
|
35
|
+
- Cross-tenant write test
|
|
36
|
+
- Test fails if the predicate is deleted
|
|
37
|
+
|
|
38
|
+
## Lifecycle
|
|
39
|
+
|
|
40
|
+
- Status: `active`
|
|
41
|
+
- Priority: `P0`
|
|
42
|
+
- Exceptions: `none`
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: SEC-006
|
|
3
|
+
title: Sessions expire, rotate and can be revoked
|
|
4
|
+
severity: MUST
|
|
5
|
+
status: active
|
|
6
|
+
domain: security
|
|
7
|
+
priority: P1
|
|
8
|
+
source:
|
|
9
|
+
- OWASP ASVS 5.0 V3
|
|
10
|
+
applies_to:
|
|
11
|
+
- api
|
|
12
|
+
- web
|
|
13
|
+
success_criteria:
|
|
14
|
+
[]
|
|
15
|
+
requirement: >
|
|
16
|
+
Sessions and tokens MUST have a bounded lifetime, MUST be rotated on privilege change, and MUST be revocable server-side. Logout MUST invalidate server state, not only client storage.
|
|
17
|
+
validation:
|
|
18
|
+
automated: false
|
|
19
|
+
manual: true
|
|
20
|
+
exceptions: documented-only
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# SEC-006 — Sessions expire, rotate and can be revoked
|
|
24
|
+
|
|
25
|
+
**Requirement:** Sessions and tokens MUST have a bounded lifetime, MUST be rotated on privilege change, and MUST be revocable server-side. Logout MUST invalidate server state, not only client storage.
|
|
26
|
+
|
|
27
|
+
**Bad:** A signed token valid for a year with no revocation list.
|
|
28
|
+
|
|
29
|
+
**Good:** Short-lived access token, rotating refresh token, revocation on logout and on password change.
|
|
30
|
+
|
|
31
|
+
## Validation
|
|
32
|
+
|
|
33
|
+
- Test: a revoked session is rejected
|
|
34
|
+
- Test: privilege change invalidates the old session
|
|
35
|
+
|
|
36
|
+
## Lifecycle
|
|
37
|
+
|
|
38
|
+
- Status: `active`
|
|
39
|
+
- Priority: `P1`
|
|
40
|
+
- Exceptions: `documented-only`
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: SEC-007
|
|
3
|
+
title: Webhooks are verified and replay-protected
|
|
4
|
+
severity: MUST
|
|
5
|
+
status: active
|
|
6
|
+
domain: security
|
|
7
|
+
priority: P0
|
|
8
|
+
source:
|
|
9
|
+
- OWASP ASVS 5.0 V13
|
|
10
|
+
applies_to:
|
|
11
|
+
- api
|
|
12
|
+
success_criteria:
|
|
13
|
+
[]
|
|
14
|
+
requirement: >
|
|
15
|
+
Inbound webhooks MUST verify the provider signature against the raw body before any processing, MUST reject stale timestamps, and MUST be idempotent on the provider event id.
|
|
16
|
+
validation:
|
|
17
|
+
automated: false
|
|
18
|
+
manual: true
|
|
19
|
+
exceptions: none
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# SEC-007 — Webhooks are verified and replay-protected
|
|
23
|
+
|
|
24
|
+
**Requirement:** Inbound webhooks MUST verify the provider signature against the raw body before any processing, MUST reject stale timestamps, and MUST be idempotent on the provider event id.
|
|
25
|
+
|
|
26
|
+
**Bad:** The handler trusts the payload and credits the account twice when the provider retries.
|
|
27
|
+
|
|
28
|
+
**Good:** Signature verified on the raw body; event id stored; a repeat delivery is a no-op that returns 200.
|
|
29
|
+
|
|
30
|
+
## Validation
|
|
31
|
+
|
|
32
|
+
- Test: bad signature rejected
|
|
33
|
+
- Test: duplicate delivery changes nothing
|
|
34
|
+
- Test: stale timestamp rejected
|
|
35
|
+
|
|
36
|
+
## Lifecycle
|
|
37
|
+
|
|
38
|
+
- Status: `active`
|
|
39
|
+
- Priority: `P0`
|
|
40
|
+
- Exceptions: `none`
|
|
41
|
+
|
|
42
|
+
## See also
|
|
43
|
+
|
|
44
|
+
- [PAYMENTS.md](../../standard/engineering/payments/PAYMENTS.md)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: SEC-008
|
|
3
|
+
title: Abuse surfaces are rate limited
|
|
4
|
+
severity: MUST
|
|
5
|
+
status: active
|
|
6
|
+
domain: security
|
|
7
|
+
priority: P1
|
|
8
|
+
source:
|
|
9
|
+
- OWASP ASVS 5.0 V11
|
|
10
|
+
applies_to:
|
|
11
|
+
- api
|
|
12
|
+
success_criteria:
|
|
13
|
+
[]
|
|
14
|
+
requirement: >
|
|
15
|
+
Authentication, password reset, invitation, search, export and any expensive or enumerable endpoint MUST be rate limited per actor and per source, and MUST fail closed when the limiter is unavailable.
|
|
16
|
+
validation:
|
|
17
|
+
automated: false
|
|
18
|
+
manual: true
|
|
19
|
+
exceptions: documented-only
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# SEC-008 — Abuse surfaces are rate limited
|
|
23
|
+
|
|
24
|
+
**Requirement:** Authentication, password reset, invitation, search, export and any expensive or enumerable endpoint MUST be rate limited per actor and per source, and MUST fail closed when the limiter is unavailable.
|
|
25
|
+
|
|
26
|
+
**Bad:** Unlimited login attempts, or a limiter that silently allows everything when its backend is down.
|
|
27
|
+
|
|
28
|
+
**Good:** Per-account and per-IP limits with a clear 429, and a closed default when the limiter cannot answer.
|
|
29
|
+
|
|
30
|
+
## Validation
|
|
31
|
+
|
|
32
|
+
- Test: the limit triggers
|
|
33
|
+
- Confirm behaviour when the limiter backend fails
|
|
34
|
+
|
|
35
|
+
## Lifecycle
|
|
36
|
+
|
|
37
|
+
- Status: `active`
|
|
38
|
+
- Priority: `P1`
|
|
39
|
+
- Exceptions: `documented-only`
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: SEC-009
|
|
3
|
+
title: Transport and browser security headers are set
|
|
4
|
+
severity: MUST
|
|
5
|
+
status: active
|
|
6
|
+
domain: security
|
|
7
|
+
priority: P1
|
|
8
|
+
source:
|
|
9
|
+
- OWASP ASVS 5.0 V9
|
|
10
|
+
applies_to:
|
|
11
|
+
- web
|
|
12
|
+
- api
|
|
13
|
+
success_criteria:
|
|
14
|
+
[]
|
|
15
|
+
requirement: >
|
|
16
|
+
Production traffic MUST be TLS only, with HSTS, a content security policy, `X-Content-Type-Options`, a referrer policy, and cookies marked `Secure`, `HttpOnly` and `SameSite` as appropriate.
|
|
17
|
+
validation:
|
|
18
|
+
automated: true
|
|
19
|
+
manual: true
|
|
20
|
+
exceptions: documented-only
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# SEC-009 — Transport and browser security headers are set
|
|
24
|
+
|
|
25
|
+
**Requirement:** Production traffic MUST be TLS only, with HSTS, a content security policy, `X-Content-Type-Options`, a referrer policy, and cookies marked `Secure`, `HttpOnly` and `SameSite` as appropriate.
|
|
26
|
+
|
|
27
|
+
**Bad:** A session cookie without `HttpOnly` on a site served over both HTTP and HTTPS.
|
|
28
|
+
|
|
29
|
+
**Good:** HTTPS enforced with redirect and HSTS; CSP without `unsafe-inline`; cookies hardened.
|
|
30
|
+
|
|
31
|
+
## Validation
|
|
32
|
+
|
|
33
|
+
- Inspect response headers on a deployed environment
|
|
34
|
+
- Check cookie flags
|
|
35
|
+
|
|
36
|
+
## Lifecycle
|
|
37
|
+
|
|
38
|
+
- Status: `active`
|
|
39
|
+
- Priority: `P1`
|
|
40
|
+
- Exceptions: `documented-only`
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: SEC-010
|
|
3
|
+
title: Least privilege for every credential and role
|
|
4
|
+
severity: MUST
|
|
5
|
+
status: active
|
|
6
|
+
domain: security
|
|
7
|
+
priority: P1
|
|
8
|
+
source:
|
|
9
|
+
- OWASP ASVS 5.0 V1
|
|
10
|
+
applies_to:
|
|
11
|
+
- service
|
|
12
|
+
- database
|
|
13
|
+
- devops
|
|
14
|
+
success_criteria:
|
|
15
|
+
[]
|
|
16
|
+
requirement: >
|
|
17
|
+
Application credentials, CI tokens and cloud roles MUST hold the narrowest set of permissions the task needs, and MUST be scoped to the environment they serve.
|
|
18
|
+
validation:
|
|
19
|
+
automated: false
|
|
20
|
+
manual: true
|
|
21
|
+
exceptions: documented-only
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# SEC-010 — Least privilege for every credential and role
|
|
25
|
+
|
|
26
|
+
**Requirement:** Application credentials, CI tokens and cloud roles MUST hold the narrowest set of permissions the task needs, and MUST be scoped to the environment they serve.
|
|
27
|
+
|
|
28
|
+
**Bad:** One database superuser shared by the app, the migration job and the analytics reader.
|
|
29
|
+
|
|
30
|
+
**Good:** A migration role that can alter schema, an app role that cannot, a read-only analytics role.
|
|
31
|
+
|
|
32
|
+
## Validation
|
|
33
|
+
|
|
34
|
+
- Review the permission set of each credential the change touches
|
|
35
|
+
|
|
36
|
+
## Lifecycle
|
|
37
|
+
|
|
38
|
+
- Status: `active`
|
|
39
|
+
- Priority: `P1`
|
|
40
|
+
- Exceptions: `documented-only`
|