@@ -37,10 +37,10 @@ export const configHardening: HardeningModule = {
3737 severity : 'CRITICAL' ,
3838 category : 'execution' ,
3939 title : 'Execution approvals disabled' ,
40- description : 'Will set exec.approvals to "always" .' ,
40+ description : 'Execution approvals are disabled. This allows commands to run without user confirmation .' ,
4141 evidence : 'exec.approvals = "off"' ,
42- remediation : 'Set exec.approvals to "always"' ,
43- autoFixable : true ,
42+ remediation : 'Manually set exec.approvals to "always" in your OpenClaw settings (not auto-fixable — key not in OpenClaw config schema) ' ,
43+ autoFixable : false ,
4444 references : [ ] ,
4545 owaspAsi : 'ASI02' ,
4646 } ) ;
@@ -52,10 +52,10 @@ export const configHardening: HardeningModule = {
5252 severity : 'MEDIUM' ,
5353 category : 'execution' ,
5454 title : 'Sandbox not set to all' ,
55- description : 'Will set sandbox. mode to "all".' ,
55+ description : 'Sandbox mode is not set to "all". Not all commands run in a sandboxed environment .' ,
5656 evidence : `sandbox.mode = "${ ctx . config . sandbox ?. mode ?? 'undefined' } "` ,
57- remediation : 'Set sandbox.mode to "all"' ,
58- autoFixable : true ,
57+ remediation : 'Manually set sandbox.mode to "all" in your OpenClaw settings (not auto-fixable — key not in OpenClaw config schema) ' ,
58+ autoFixable : false ,
5959 references : [ ] ,
6060 owaspAsi : 'ASI05' ,
6161 } ) ;
@@ -98,32 +98,12 @@ export const configHardening: HardeningModule = {
9898
9999 const config = await readConfig ( ctx . stateDir ) ;
100100
101- // 1. Enable approval mode
102- if ( ! config . exec ) config . exec = { } ;
103- const oldApprovals = config . exec . approvals ;
104- if ( oldApprovals !== 'always' ) {
105- config . exec . approvals = 'always' ;
106- applied . push ( {
107- id : 'config-approvals' ,
108- description : 'Set exec.approvals to "always"' ,
109- before : oldApprovals ?? 'undefined' ,
110- after : 'always' ,
111- } ) ;
112- }
113-
114- // 2. Force sandbox execution
115- if ( ! config . sandbox ) config . sandbox = { } ;
116- const oldSandboxMode = config . sandbox . mode ;
117- if ( oldSandboxMode !== 'all' ) {
118- config . sandbox . mode = 'all' ;
119- applied . push ( {
120- id : 'config-sandbox-mode' ,
121- description : 'Set sandbox.mode to "all"' ,
122- before : oldSandboxMode ?? 'undefined' ,
123- after : 'all' ,
124- } ) ;
125- }
101+ // NOTE: We only write keys that OpenClaw's runtime schema accepts.
102+ // Keys like exec.approvals, exec.autoApprove, sandbox.mode are NOT
103+ // valid in OpenClaw's config and would cause "Invalid config" errors.
104+ // Those settings are reported as audit findings with manual remediation.
126105
106+ // 1. Set tools.exec.host to sandbox (valid OpenClaw key)
127107 if ( ! config . tools ) config . tools = { } ;
128108 if ( ! config . tools . exec ) config . tools . exec = { } ;
129109 const oldExecHost = config . tools . exec . host ;
@@ -137,23 +117,7 @@ export const configHardening: HardeningModule = {
137117 } ) ;
138118 }
139119
140- // 3. Disable auto-approval
141- if ( ! config . exec . autoApprove || config . exec . autoApprove . length > 0 ) {
142- config . exec . autoApprove = [ ] ;
143- applied . push ( {
144- id : 'config-auto-approve' ,
145- description : 'Cleared exec.autoApprove list' ,
146- before : 'had auto-approved commands' ,
147- after : '[] (nothing auto-approved)' ,
148- } ) ;
149- }
150-
151- // 4. Set DM policy to pairing for open channels
152- // Note: Channel configs are typically separate but we handle them via the main config
153- // In a real deployment, each channel has its own config.
154- // We'll store the fix intent in secureclaw config.
155-
156- // 5. Enable DM session isolation
120+ // 2. Enable DM session isolation (valid OpenClaw key)
157121 if ( ! config . session ) config . session = { } ;
158122 const oldDmScope = config . session . dmScope ;
159123 if ( oldDmScope !== 'per-channel-peer' ) {
@@ -166,7 +130,7 @@ export const configHardening: HardeningModule = {
166130 } ) ;
167131 }
168132
169- // 6 . Enable sensitive log redaction
133+ // 3 . Enable sensitive log redaction (valid OpenClaw key)
170134 if ( ! config . logging ) config . logging = { } ;
171135 const oldRedact = config . logging . redactSensitive ;
172136 if ( oldRedact !== 'tools' ) {
@@ -179,6 +143,28 @@ export const configHardening: HardeningModule = {
179143 } ) ;
180144 }
181145
146+ // 4. Strip keys that are NOT in OpenClaw's config schema to avoid
147+ // "Invalid config" / "Unrecognized key" errors on startup.
148+ const configAny = config as Record < string , unknown > ;
149+ if ( configAny [ 'exec' ] ) {
150+ delete configAny [ 'exec' ] ;
151+ applied . push ( {
152+ id : 'config-strip-exec' ,
153+ description : 'Removed invalid root-level "exec" key (not in OpenClaw schema)' ,
154+ before : 'present' ,
155+ after : 'removed' ,
156+ } ) ;
157+ }
158+ if ( configAny [ 'sandbox' ] ) {
159+ delete configAny [ 'sandbox' ] ;
160+ applied . push ( {
161+ id : 'config-strip-sandbox' ,
162+ description : 'Removed invalid root-level "sandbox" key (not in OpenClaw schema)' ,
163+ before : 'present' ,
164+ after : 'removed' ,
165+ } ) ;
166+ }
167+
182168 await writeConfig ( ctx . stateDir , config ) ;
183169 } catch ( err ) {
184170 errors . push ( `Config hardening error: ${ err instanceof Error ? err . message : String ( err ) } ` ) ;
0 commit comments