Skip to content

Commit fa1f820

Browse files
riaworksclaude
andauthored
Add security hardening for post-install validator with Ed25519 manifest signature verification (#56)
Merge PR #56: Security hardening for post-install validator (Story 6.19) Security controls implemented: - Ed25519 manifest signature verification (minisign) - Path traversal prevention (7 attack vectors) - Schema validation (reject unknown fields) - DoS protection limits - Symlink rejection - YAML FAILSAFE_SCHEMA Follow-up: Issue #60 created for TOCTOU symlink checks in repair method. Co-Authored-By: Claude <noreply@anthropic.com>
1 parent b0a3b79 commit fa1f820

File tree

14 files changed

+3892
-24
lines changed

14 files changed

+3892
-24
lines changed

.aios-core/cli/commands/validate/index.js

Lines changed: 429 additions & 0 deletions
Large diffs are not rendered by default.

.aios-core/install-manifest.yaml

Lines changed: 140 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
# - File types for categorization
99
#
1010
version: 3.10.0
11-
generated_at: "2026-01-29T15:28:02.428Z"
11+
generated_at: "2026-01-29T20:09:24.040Z"
1212
generator: scripts/generate-install-manifest.js
13-
file_count: 736
13+
file_count: 766
1414
files:
1515
- path: cli/commands/generate/index.js
1616
hash: sha256:36f8e38ab767fa5478d8dabac548c66dc2c0fc521c216e954ac33fcea0ba597b
@@ -108,6 +108,10 @@ files:
108108
hash: sha256:bc993858504617a233ce191ab44a438f675605022e43375d282f589a734b6c64
109109
type: cli
110110
size: 5320
111+
- path: cli/commands/validate/index.js
112+
hash: sha256:4dff9d9eaef8226018cd85b7d5f1d5a9a70f5aeee3fa7ede10f87b5eea67fd88
113+
type: cli
114+
size: 9493
111115
- path: cli/commands/workers/formatters/info-formatter.js
112116
hash: sha256:6f0d25f4033828616656178c55e50d1eeec9457279807c1b06e111d9dd79c53e
113117
type: cli
@@ -663,11 +667,11 @@ files:
663667
- path: core/registry/registry-schema.json
664668
hash: sha256:02bc6cce5b4d7491e0c7cbfb27d50658196d231a96b34d39f0414c583f45d44e
665669
type: core
666-
size: 5445
670+
size: 5279
667671
- path: core/registry/service-registry.json
668672
hash: sha256:00f18727622526faaef558b17840d62b149a112eeb82cb3e645849e1b72db981
669673
type: core
670-
size: 167814
674+
size: 161229
671675
- path: core/registry/validate-registry.js
672676
hash: sha256:f49bcf208b62fabdac40d28093e08d564cf0f1a175a8ac2c05cf987208bb907d
673677
type: core
@@ -2395,7 +2399,47 @@ files:
23952399
- path: manifests/schema/manifest-schema.json
23962400
hash: sha256:39678986089918893f309a2469fa0615beb82b5c6f1e16e2f9b40bcac6465195
23972401
type: manifest
2398-
size: 5481
2402+
size: 5291
2403+
- path: monitor/hooks/lib/__init__.py
2404+
hash: sha256:26147f29392400ed7bb87ca750af1c1bdd191193990463952282eaaffc1f35a2
2405+
type: monitor
2406+
size: 30
2407+
- path: monitor/hooks/lib/enrich.py
2408+
hash: sha256:f796c327b54e5282027babe325f9629ad21440275c2a3fdb277840898bdf3653
2409+
type: monitor
2410+
size: 1702
2411+
- path: monitor/hooks/lib/send_event.py
2412+
hash: sha256:2ec9ec9abfded4c0b67a49429d192f171758c0fb4e8a1bf1e47f2c8e32aa47ea
2413+
type: monitor
2414+
size: 1237
2415+
- path: monitor/hooks/notification.py
2416+
hash: sha256:ae9e484772e090c557fcda3be46d19b9c48d7bec9789652cbfec17d7616a956f
2417+
type: monitor
2418+
size: 528
2419+
- path: monitor/hooks/post_tool_use.py
2420+
hash: sha256:5599de99f3292ce7b57ad754abe9a0bfb462b1babc95a2bab22016528eb2515b
2421+
type: monitor
2422+
size: 1185
2423+
- path: monitor/hooks/pre_compact.py
2424+
hash: sha256:df11373948b986814a7602a9dd61a384055de13392a7aa246063b4c4ea75fddd
2425+
type: monitor
2426+
size: 529
2427+
- path: monitor/hooks/pre_tool_use.py
2428+
hash: sha256:e4a7bbd6cbb6e17b819f629ef88a24947612f4dffbe19fab897b9ff4a409efc2
2429+
type: monitor
2430+
size: 1021
2431+
- path: monitor/hooks/stop.py
2432+
hash: sha256:9737bcedd34cfdf459641e2f0e74eacf7a56d0e7ad0fb05a32a40c0afc87443e
2433+
type: monitor
2434+
size: 519
2435+
- path: monitor/hooks/subagent_stop.py
2436+
hash: sha256:cfe2b5361a0b668f90d738bcd18f478e2ea49459304b203608377a1226d2bebb
2437+
type: monitor
2438+
size: 541
2439+
- path: monitor/hooks/user_prompt_submit.py
2440+
hash: sha256:f8f9a7550121832811c2d2d12b93d5d42fa7180ddec85c49ae3841c9d259ab76
2441+
type: monitor
2442+
size: 856
23992443
- path: package.json
24002444
hash: sha256:9998a56094f4a308c534d4dd9b29721ef50aabc0c50633763f5c1ac7b7f3da48
24012445
type: other
@@ -2579,7 +2623,7 @@ files:
25792623
- path: product/templates/component-react-tmpl.tsx
25802624
hash: sha256:bfbfab502da2064527948f70c9a59174f20b81472ac2ea6eb999f02c9bcaf3df
25812625
type: template
2582-
size: 2686
2626+
size: 2588
25832627
- path: product/templates/current-approach-tmpl.md
25842628
hash: sha256:ec258049a5cda587b24523faf6b26ed0242765f4e732af21c4f42e42cf326714
25852629
type: template
@@ -2615,35 +2659,35 @@ files:
26152659
- path: product/templates/engine/schemas/adr.schema.json
26162660
hash: sha256:2cd4c78d9c2664695df163d033709122b0b37c70fd4f92c9bf4ea17503d4db0b
26172661
type: template
2618-
size: 3017
2662+
size: 2915
26192663
- path: product/templates/engine/schemas/dbdr.schema.json
26202664
hash: sha256:9d5f4e3774830f545617e801ec24ea6649afb2ab217fffda4f6fa3ec5136f2ea
26212665
type: template
2622-
size: 5936
2666+
size: 5731
26232667
- path: product/templates/engine/schemas/epic.schema.json
26242668
hash: sha256:c2e898276cf89338b9fa8d619c18c40d1ed1e4390d63cc779b439c37380a5317
26252669
type: template
2626-
size: 4666
2670+
size: 4491
26272671
- path: product/templates/engine/schemas/pmdr.schema.json
26282672
hash: sha256:3e3883d552f2fa0f1b9cd6d1621e9788858d81f2c9faa66fbdfc20744cddf855
26292673
type: template
2630-
size: 4964
2674+
size: 4789
26312675
- path: product/templates/engine/schemas/prd-v2.schema.json
26322676
hash: sha256:b6a5fcb6aa6ba4417f55673f2432fdc96d3b178ccd494b56796b74271cbe9ebe
26332677
type: template
2634-
size: 8122
2678+
size: 7822
26352679
- path: product/templates/engine/schemas/prd.schema.json
26362680
hash: sha256:a68c16308518ee12339d63659bef8b145d0101dcf7fe1e4e06ccad1c20a4b61a
26372681
type: template
2638-
size: 4458
2682+
size: 4306
26392683
- path: product/templates/engine/schemas/story.schema.json
26402684
hash: sha256:23d037e35a7ebecc6af86ef30223b2c20e3a938a4c9f4b6ca18a8cec6646a005
26412685
type: template
2642-
size: 6106
2686+
size: 5884
26432687
- path: product/templates/engine/schemas/task.schema.json
26442688
hash: sha256:01ed077417b76d54bb2aa93f94d3ca4b9587bb957dd269ff31f7f707f1efda37
26452689
type: template
2646-
size: 4010
2690+
size: 3856
26472691
- path: product/templates/engine/validator.js
26482692
hash: sha256:159422012586b65933dca98f7cc0274ebc8a867c79533340b548fc9eaca41944
26492693
type: template
@@ -2655,7 +2699,7 @@ files:
26552699
- path: product/templates/eslintrc-security.json
26562700
hash: sha256:657d40117261d6a52083984d29f9f88e79040926a64aa4c2058a602bfe91e0d5
26572701
type: template
2658-
size: 941
2702+
size: 909
26592703
- path: product/templates/front-end-architecture-tmpl.yaml
26602704
hash: sha256:de0432b4f98236c3a1d6cc9975b90fbc57727653bdcf6132355c0bcf0b4dbb9c
26612705
type: template
@@ -2671,11 +2715,11 @@ files:
26712715
- path: product/templates/github-actions-cd.yml
26722716
hash: sha256:c9ef00ed1a691d634bb6a4927b038c96dcbc65e4337432eb2075e9ef302af85b
26732717
type: template
2674-
size: 7204
2718+
size: 6992
26752719
- path: product/templates/github-actions-ci.yml
26762720
hash: sha256:b64abbfdaf10b61d28ce0391fbcc2c54136cf14f4996244808341bb5ced0168e
26772721
type: template
2678-
size: 4664
2722+
size: 4492
26792723
- path: product/templates/github-pr-template.md
26802724
hash: sha256:f04dc7a2a98f3ada40a54a62d93ed2ee289c4b11032ef420acf10fbfe19d1dc5
26812725
type: template
@@ -2799,7 +2843,7 @@ files:
27992843
- path: product/templates/shock-report-tmpl.html
28002844
hash: sha256:f6b3984683b9c0e22550aaab63f002c01d6d9d3fe2af0e344f7dafbd444e4a19
28012845
type: template
2802-
size: 17167
2846+
size: 16665
28032847
- path: product/templates/spec-tmpl.md
28042848
hash: sha256:5f3a97a1d4cc5c0fe81432d942cdd3ac2ec43c6785c3594ba3e1070601719718
28052849
type: template
@@ -2891,7 +2935,7 @@ files:
28912935
- path: product/templates/token-exports-css-tmpl.css
28922936
hash: sha256:d937b8d61cdc9e5b10fdff871c6cb41c9f756004d060d671e0ae26624a047f62
28932937
type: template
2894-
size: 6038
2938+
size: 5798
28952939
- path: product/templates/token-exports-tailwind-tmpl.js
28962940
hash: sha256:1e99f1be493b4b3dac1b2a9abc1ae1dd9146f26f86bed229c232690114c3a377
28972941
type: template
@@ -2927,7 +2971,7 @@ files:
29272971
- path: scripts/migrate-framework-docs.sh
29282972
hash: sha256:b453931ec91e85b7f2e71d8508960e742aaa85fa44a89221ff257d472ab61ca3
29292973
type: script
2930-
size: 9788
2974+
size: 9488
29312975
- path: scripts/README.md
29322976
hash: sha256:197f6f703ec52c1e2c5ea0468b6cd8031ed7b9b4b563887dcd8c4a388efee059
29332977
type: script
@@ -2952,6 +2996,82 @@ files:
29522996
hash: sha256:abcef62ecd991d311ef2b1858ae14aeed76e7e9d3579fab73760936926c57553
29532997
type: documentation
29542998
size: 38581
2999+
- path: workflow-intelligence/__tests__/confidence-scorer.test.js
3000+
hash: sha256:237216842d3eb710ae33f3aba6c7b2a6a353cccc1dea6d4b927d8d063d9cb635
3001+
type: workflow-intelligence
3002+
size: 10679
3003+
- path: workflow-intelligence/__tests__/integration.test.js
3004+
hash: sha256:e7550505c820acc79cc2cab65325aeacdc9663e29acb473b815fa252d5eb9637
3005+
type: workflow-intelligence
3006+
size: 11097
3007+
- path: workflow-intelligence/__tests__/suggestion-engine.test.js
3008+
hash: sha256:661953a509222af58839e7142d8d7242128f56de2e2e2f009df924c6c4e8e346
3009+
type: workflow-intelligence
3010+
size: 12786
3011+
- path: workflow-intelligence/__tests__/wave-analyzer.test.js
3012+
hash: sha256:617a099d4be72f8711a4be734ed0a600d97f7e84bec24edf8b97d68b6c5a2b51
3013+
type: workflow-intelligence
3014+
size: 15055
3015+
- path: workflow-intelligence/__tests__/workflow-registry.test.js
3016+
hash: sha256:fee70788995d95180f647eea86a012d1f90d8157405c9abf3d8004e1e347a424
3017+
type: workflow-intelligence
3018+
size: 9967
3019+
- path: workflow-intelligence/engine/confidence-scorer.js
3020+
hash: sha256:6ab69ac846e0f3b49fd7d76a720ab1dc305f402b54518bbcf8ce876f269d0c18
3021+
type: workflow-intelligence
3022+
size: 8822
3023+
- path: workflow-intelligence/engine/output-formatter.js
3024+
hash: sha256:14187bd3e45b55fbbbdf89841df8f308ce8877587ce4eeb9c014fd4a37b0c447
3025+
type: workflow-intelligence
3026+
size: 8428
3027+
- path: workflow-intelligence/engine/suggestion-engine.js
3028+
hash: sha256:5c6a5e7a6f247b3cd180dd795e8317de72efe2ee63558f25dc158976d2c6d2dd
3029+
type: workflow-intelligence
3030+
size: 19805
3031+
- path: workflow-intelligence/engine/wave-analyzer.js
3032+
hash: sha256:e6e66cd3d54542368f46fa53ca30852e5468f2137c6b5f7f510d63bec3f62555
3033+
type: workflow-intelligence
3034+
size: 19796
3035+
- path: workflow-intelligence/index.js
3036+
hash: sha256:f0cfbf0ada6a915d6188b3dbd7dd9a950afdf337fda0df4fcc7fb2e3d2758155
3037+
type: workflow-intelligence
3038+
size: 8190
3039+
- path: workflow-intelligence/learning/capture-hook.js
3040+
hash: sha256:94898ad234acb6d0ffa8952952ac43fe5cea5267a750719e3a602564c7c9b73a
3041+
type: workflow-intelligence
3042+
size: 3264
3043+
- path: workflow-intelligence/learning/gotcha-registry.js
3044+
hash: sha256:ebac4cdc6279712e7acb022a75cd80f47dcbb0f7d349a97f7bd972c65d04d39e
3045+
type: workflow-intelligence
3046+
size: 21114
3047+
- path: workflow-intelligence/learning/index.js
3048+
hash: sha256:02fc847fa47ad36265cd32fdf14e840397c181218c367be56df77f249f2f4567
3049+
type: workflow-intelligence
3050+
size: 7321
3051+
- path: workflow-intelligence/learning/pattern-capture.js
3052+
hash: sha256:241eee4c4923643707680484899d0c84fb8835ca0df972900fdc917f22b990f6
3053+
type: workflow-intelligence
3054+
size: 9359
3055+
- path: workflow-intelligence/learning/pattern-store.js
3056+
hash: sha256:7f1b26f4a4e86e592af0e714443626e9e1e8d98784aac24c346e6bc1b496eeb5
3057+
type: workflow-intelligence
3058+
size: 13680
3059+
- path: workflow-intelligence/learning/pattern-validator.js
3060+
hash: sha256:9ee02dbbfd1e885048c8cdf753946b42f318667a9ccfe44ee737ab72d23ca2f8
3061+
type: workflow-intelligence
3062+
size: 8543
3063+
- path: workflow-intelligence/learning/qa-feedback.js
3064+
hash: sha256:1463f9b27321d5f88966d62e8deaa2521472a7020eedd4d8de8068c56d0f39db
3065+
type: workflow-intelligence
3066+
size: 18405
3067+
- path: workflow-intelligence/learning/semantic-search.js
3068+
hash: sha256:3b3255f7bd6a940dc14bda33a6b02f1f166aa97cb95812d369d92ec972030e39
3069+
type: workflow-intelligence
3070+
size: 16679
3071+
- path: workflow-intelligence/registry/workflow-registry.js
3072+
hash: sha256:575103b7ece3accbe7103cfe17622f8fe8d8c7088d1ff6c62fc7f46f7dc0ee81
3073+
type: workflow-intelligence
3074+
size: 9398
29553075
- path: working-in-the-brownfield.md
29563076
hash: sha256:3daeaf85acb49578b29eed2085736274a5d144e3eaec53738d9220362442fd7d
29573077
type: documentation

.eslintcache

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,3 +297,5 @@ npm-recovery-codes.txt
297297
# Windows path-encoded temporary files (malformed path files)
298298
C:Users*
299299
*temp-catalog.txt
300+
.eslintcache
301+
.eslintcache

bin/aios-init.js

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,57 @@ See .aios-core/user-guide.md for complete documentation.
804804
}
805805
}
806806

807+
// Post-installation validation (Story 6.19)
808+
console.log('');
809+
console.log(chalk.blue('🔍 Validating installation integrity...'));
810+
811+
let validationPassed = true;
812+
try {
813+
const { PostInstallValidator } = require('../src/installer/post-install-validator');
814+
const validator = new PostInstallValidator(context.projectRoot, context.frameworkLocation, {
815+
verifyHashes: false,
816+
verbose: false,
817+
// SECURITY NOTE: Signature verification is disabled during initial installation
818+
// because the manifest signature (.minisig) may not yet be present in the package.
819+
// This is acceptable for post-install validation which only checks file presence.
820+
// For production integrity checks, users should run `aios validate` which
821+
// enforces signature verification when the .minisig file is present.
822+
requireSignature: false,
823+
});
824+
825+
const report = await validator.validate();
826+
827+
if (
828+
report.status === 'failed' ||
829+
report.stats.missingFiles > 0 ||
830+
report.stats.corruptedFiles > 0
831+
) {
832+
validationPassed = false;
833+
console.log(chalk.yellow('⚠') + ` Installation validation found issues:`);
834+
console.log(chalk.dim(` - Missing files: ${report.stats.missingFiles}`));
835+
console.log(chalk.dim(` - Corrupted files: ${report.stats.corruptedFiles}`));
836+
console.log('');
837+
console.log(
838+
chalk.yellow(' Run ') +
839+
chalk.cyan('aios validate --repair') +
840+
chalk.yellow(' to fix issues')
841+
);
842+
} else {
843+
console.log(chalk.green('✓') + ` Installation verified (${report.stats.validFiles} files)`);
844+
}
845+
} catch (validationError) {
846+
// Log validation errors but don't fail installation
847+
// This allows installation to proceed even if validator module has issues
848+
// However, users should investigate validation errors manually
849+
validationPassed = false;
850+
console.log(chalk.yellow('⚠') + ' Post-installation validation encountered an error');
851+
console.log(chalk.dim(` Error: ${validationError.message}`));
852+
if (process.env.DEBUG || process.env.AIOS_DEBUG) {
853+
console.log(chalk.dim(` Stack: ${validationError.stack}`));
854+
}
855+
console.log(chalk.dim(' Run `aios validate` to check installation integrity'));
856+
}
857+
807858
// Summary
808859
console.log('');
809860
console.log(chalk.gray('═'.repeat(80)));
@@ -918,9 +969,8 @@ See .aios-core/user-guide.md for complete documentation.
918969
}
919970

920971
console.log(' ' + chalk.yellow('General:'));
921-
console.log(
922-
' • Run ' + chalk.yellow('"@synkra/aios-core doctor"') + ' to verify installation'
923-
);
972+
console.log(' • Run ' + chalk.yellow('aios validate') + ' to verify installation integrity');
973+
console.log(' • Run ' + chalk.yellow('aios validate --repair') + ' to fix any missing files');
924974
console.log(' • Check .aios-core/user-guide.md for complete documentation');
925975
console.log(' • Explore expansion-packs/ for additional capabilities');
926976
console.log('');

0 commit comments

Comments
 (0)