Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0ad31dd

Browse files
authored
impl: add support for disabling CLI signature verification (#166)
This PR implements a new configurable option to allow users to disableGPG signature verification for downloaded Coder CLI binaries. Thisfeature provides flexibility for environments where signatureverification may not be required or where fallback signature sources arenot accessible.A new option `disableSignatureVerification` is now available only fromthe Settings page, with no quick shortcut in the main page to discourageusers from quickly disabling this option. The`fallbackOnCoderForSignatures` is hidden/not available for configurationonce signature verification is disabled.Additionally a rough draft for developer facing documentation regardingCLI signature verification was added.To make things more consistent with Coder Gateway, the fallback settingis always displayed if signature verification is enabled, we no longerdisplay it only once in the main page.This PR is a port ofcoder/jetbrains-coder#564from Coder Gateway.<img width="486" height="746" alt="image"src="https://github.com/user-attachments/assets/eff6f944-57ea-4926-857a-d5c5fd5d3901"/><img width="486" height="746" alt="image"src="https://github.com/user-attachments/assets/7f1d39da-9777-4d5c-a329-e056fe38bf22"/>
1 parent82eee1f commit0ad31dd

File tree

11 files changed

+116
-10
lines changed

11 files changed

+116
-10
lines changed

‎CHANGELOG.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
##Unreleased
44

5+
###Added
6+
7+
- support for skipping CLI signature verification
8+
59
###Changed
610

711
- URL validation is stricter in the connection screen and URI protocol handler

‎JETBRAINS_COMPLIANCE.md‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ This configuration includes JetBrains-specific rules that check for:
3939
-**ForbiddenImport**: Detects potentially bundled libraries
4040
-**Standard code quality rules**: Complexity, naming, performance, etc.
4141

42-
43-
4442
##CI/CD Integration
4543

4644
The GitHub Actions workflow`.github/workflows/jetbrains-compliance.yml` runs compliance checks on every PR and push.
@@ -55,8 +53,6 @@ The GitHub Actions workflow `.github/workflows/jetbrains-compliance.yml` runs co
5553
open build/reports/detekt/detekt.html
5654
```
5755

58-
59-
6056
##Understanding Results
6157

6258
###Compliance Check Results

‎README.md‎

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,69 @@ If `ide_product_code` and `ide_build_number` is missing, Toolbox will only open
109109
page. Coder Toolbox will attempt to start the workspace if it’s not already running; however, for the most reliable
110110
experience, it’s recommended to ensure the workspace is running prior to initiating the connection.
111111

112+
##GPG Signature Verification
113+
114+
The Coder Toolbox plugin starting with version*0.5.0* implements a comprehensive GPG signature verification system to
115+
ensure the authenticity and integrity of downloaded Coder CLI binaries. This security feature helps protect users from
116+
running potentially malicious or tampered binaries.
117+
118+
###How It Works
119+
120+
1.**Binary Download**: When connecting to a Coder deployment, the plugin downloads the appropriate Coder CLI binary for
121+
the user's operating system and architecture from the deployment's`/bin/` endpoint.
122+
123+
2.**Signature Download**: After downloading the binary, the plugin attempts to download the corresponding`.asc`
124+
signature file from the same location. The signature file is named according to the binary (e.g.,
125+
`coder-linux-amd64.asc` for`coder-linux-amd64`).
126+
127+
3.**Fallback Signature Sources**: If the signature is not available from the deployment, the plugin can optionally fall
128+
back to downloading signatures from`releases.coder.com`. This is controlled by the`fallbackOnCoderForSignatures`
129+
setting.
130+
131+
4.**GPG Verification**: The plugin uses the BouncyCastle library to verify the detached GPG signature against the
132+
downloaded binary using Coder's trusted public key.
133+
134+
5.**User Interaction**: If signature verification fails or signatures are unavailable, the plugin presents security
135+
warnings to users, allowing them to accept the risk and continue or abort the operation.
136+
137+
###Verification Process
138+
139+
The verification process involves several components:
140+
141+
-**`GPGVerifier`**: Handles the core GPG signature verification logic using BouncyCastle
142+
-**`VerificationResult`**: Represents the outcome of verification (Valid, Invalid, Failed, SignatureNotFound)
143+
-**`CoderDownloadService`**: Manages downloading both binaries and their signatures
144+
-**`CoderCLIManager`**: Orchestrates the download and verification workflow
145+
146+
###Configuration Options
147+
148+
Users can control signature verification behavior through plugin settings:
149+
150+
-**`disableSignatureVerification`**: When enabled, skips all signature verification. This is useful for clients running
151+
custom CLI builds, or customers with old deployment versions that don't have a signature published on
152+
`releases.coder.com`.
153+
-**`fallbackOnCoderForSignatures`**: When enabled, allows downloading signatures from`releases.coder.com` if not
154+
available from the deployment.
155+
156+
###Security Considerations
157+
158+
- The plugin embeds Coder's trusted public key in the plugin resources
159+
- Verification uses detached signatures, which are more secure than attached signatures
160+
- Users are warned about security risks when verification fails
161+
- The system gracefully handles cases where signatures are unavailable
162+
- All verification failures are logged for debugging purposes
163+
164+
###Error Handling
165+
166+
The system handles various failure scenarios:
167+
168+
-**Missing signatures**: Prompts user to accept risk or abort
169+
-**Invalid signatures**: Warns user about potential tampering and prompts user to accept risk or abort
170+
-**Verification failures**: Prompts user to accept risk or abort
171+
172+
This signature verification system ensures that users can trust the Coder CLI binaries they download through the plugin,
173+
protecting against supply chain attacks and ensuring binary integrity.
174+
112175
##Configuring and Testing workspace polling with HTTP & SOCKS5 Proxy
113176

114177
This section explains how to set up a local proxy and verify that

‎gradle.properties‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
version=0.6.0
1+
version=0.6.1
22
group=com.coder.toolbox
33
name=coder-toolbox

‎src/main/kotlin/com/coder/toolbox/cli/CoderCLIManager.kt‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,12 @@ class CoderCLIManager(
181181
}
182182
}
183183

184+
if (context.settingsStore.disableSignatureVerification) {
185+
downloader.commit()
186+
context.logger.info("Skipping over CLI signature verification, it is disabled by the user")
187+
returntrue
188+
}
189+
184190
var signatureResult= withContext(Dispatchers.IO) {
185191
downloader.downloadSignature(showTextProgress)
186192
}

‎src/main/kotlin/com/coder/toolbox/settings/ReadOnlyCoderSettings.kt‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,12 @@ interface ReadOnlyCoderSettings {
2929
val binaryDirectory:String?
3030

3131
/**
32-
* Controls whether we fall back release.coder.com
32+
* Controls whether we verify the cli signature
33+
*/
34+
val disableSignatureVerification:Boolean
35+
36+
/**
37+
* Controls whether we fall back on release.coder.com for signatures if signature validation is enabled
3338
*/
3439
val fallbackOnCoderForSignatures:SignatureFallbackStrategy
3540

‎src/main/kotlin/com/coder/toolbox/store/CoderSettingsStore.kt‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class CoderSettingsStore(
3838
overrideval defaultURL:String get()= store[DEFAULT_URL]?:"https://dev.coder.com"
3939
overrideval binarySource:String? get()= store[BINARY_SOURCE]
4040
overrideval binaryDirectory:String? get()= store[BINARY_DIRECTORY]
41+
overrideval disableSignatureVerification:Boolean
42+
get()= store[DISABLE_SIGNATURE_VALIDATION]?.toBooleanStrictOrNull()?:false
4143
overrideval fallbackOnCoderForSignatures:SignatureFallbackStrategy
4244
get()=SignatureFallbackStrategy.fromValue(store[FALLBACK_ON_CODER_FOR_SIGNATURES])
4345
overrideval defaultCliBinaryNameByOsAndArch:String get()= getCoderCLIForOS(getOS(), getArch())
@@ -166,6 +168,10 @@ class CoderSettingsStore(
166168
store[ENABLE_DOWNLOADS]= shouldEnableDownloads.toString()
167169
}
168170

171+
funupdateDisableSignatureVerification(shouldDisableSignatureVerification:Boolean) {
172+
store[DISABLE_SIGNATURE_VALIDATION]= shouldDisableSignatureVerification.toString()
173+
}
174+
169175
funupdateSignatureFallbackStrategy(fallback:Boolean) {
170176
store[FALLBACK_ON_CODER_FOR_SIGNATURES]=when (fallback) {
171177
true->SignatureFallbackStrategy.ALLOW.toString()

‎src/main/kotlin/com/coder/toolbox/store/StoreKeys.kt‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ internal const val BINARY_SOURCE = "binarySource"
1010

1111
internalconstvalBINARY_DIRECTORY="binaryDirectory"
1212

13+
internalconstvalDISABLE_SIGNATURE_VALIDATION="disableSignatureValidation"
14+
1315
internalconstvalFALLBACK_ON_CODER_FOR_SIGNATURES="signatureFallbackStrategy"
1416

1517
internalconstvalBINARY_NAME="binaryName"

‎src/main/kotlin/com/coder/toolbox/views/CoderSettingsPage.kt‎

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.jetbrains.toolbox.api.ui.components.CheckboxField
66
importcom.jetbrains.toolbox.api.ui.components.TextField
77
importcom.jetbrains.toolbox.api.ui.components.TextType
88
importcom.jetbrains.toolbox.api.ui.components.UiField
9+
importkotlinx.coroutines.Job
910
importkotlinx.coroutines.channels.Channel
1011
importkotlinx.coroutines.channels.ClosedSendChannelException
1112
importkotlinx.coroutines.flow.MutableStateFlow
@@ -20,7 +21,7 @@ import kotlinx.coroutines.launch
2021
* TODO@JB: There is no scroll, and our settings do not fit. As a consequence,
2122
* I have not been able to test this page.
2223
*/
23-
classCoderSettingsPage(context:CoderToolboxContext,triggerSshConfig:Channel<Boolean>) :
24+
classCoderSettingsPage(privatevalcontext:CoderToolboxContext,triggerSshConfig:Channel<Boolean>) :
2425
CoderPage(MutableStateFlow(context.i18n.ptrl("Coder Settings")),false) {
2526
privateval settings= context.settingsStore.readOnly()
2627

@@ -33,6 +34,11 @@ class CoderSettingsPage(context: CoderToolboxContext, triggerSshConfig: Channel<
3334
TextField(context.i18n.ptrl("Data directory"), settings.dataDirectory?:"",TextType.General)
3435
privateval enableDownloadsField=
3536
CheckboxField(settings.enableDownloads, context.i18n.ptrl("Enable downloads"))
37+
38+
privateval disableSignatureVerificationField=CheckboxField(
39+
settings.disableSignatureVerification,
40+
context.i18n.ptrl("Disable Coder CLI signature verification")
41+
)
3642
privateval signatureFallbackStrategyField=
3743
CheckboxField(
3844
settings.fallbackOnCoderForSignatures.isAllowed(),
@@ -65,13 +71,14 @@ class CoderSettingsPage(context: CoderToolboxContext, triggerSshConfig: Channel<
6571
privateval networkInfoDirField=
6672
TextField(context.i18n.ptrl("SSH network metrics directory"), settings.networkInfoDir,TextType.General)
6773

68-
74+
privatelateinitvar visibilityUpdateJob:Job
6975
overrideval fields:StateFlow<List<UiField>>=MutableStateFlow(
7076
listOf(
7177
binarySourceField,
7278
enableDownloadsField,
7379
binaryDirectoryField,
7480
enableBinaryDirectoryFallbackField,
81+
disableSignatureVerificationField,
7582
signatureFallbackStrategyField,
7683
dataDirectoryField,
7784
headerCommandField,
@@ -94,6 +101,7 @@ class CoderSettingsPage(context: CoderToolboxContext, triggerSshConfig: Channel<
94101
context.settingsStore.updateBinaryDirectory(binaryDirectoryField.contentState.value)
95102
context.settingsStore.updateDataDirectory(dataDirectoryField.contentState.value)
96103
context.settingsStore.updateEnableDownloads(enableDownloadsField.checkedState.value)
104+
context.settingsStore.updateDisableSignatureVerification(disableSignatureVerificationField.checkedState.value)
97105
context.settingsStore.updateSignatureFallbackStrategy(signatureFallbackStrategyField.checkedState.value)
98106
context.settingsStore.updateBinaryDirectoryFallback(enableBinaryDirectoryFallbackField.checkedState.value)
99107
context.settingsStore.updateHeaderCommand(headerCommandField.contentState.value)
@@ -182,5 +190,19 @@ class CoderSettingsPage(context: CoderToolboxContext, triggerSshConfig: Channel<
182190
networkInfoDirField.contentState.update {
183191
settings.networkInfoDir
184192
}
193+
194+
visibilityUpdateJob= context.cs.launch {
195+
disableSignatureVerificationField.checkedState.collect { state->
196+
signatureFallbackStrategyField.visibility.update {
197+
// the fallback checkbox should not be visible
198+
// if signature verification is disabled
199+
!state
200+
}
201+
}
202+
}
203+
}
204+
205+
overridefunafterHide() {
206+
visibilityUpdateJob.cancel()
185207
}
186208
}

‎src/main/kotlin/com/coder/toolbox/views/DeploymentUrlStep.kt‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
packagecom.coder.toolbox.views
22

33
importcom.coder.toolbox.CoderToolboxContext
4-
importcom.coder.toolbox.settings.SignatureFallbackStrategy
54
importcom.coder.toolbox.util.WebUrlValidationResult.Invalid
65
importcom.coder.toolbox.util.toURL
76
importcom.coder.toolbox.util.validateStrictWebUrl
@@ -41,7 +40,7 @@ class DeploymentUrlStep(
4140

4241
overrideval panel:RowGroup
4342
get() {
44-
if (context.settingsStore.fallbackOnCoderForSignatures==SignatureFallbackStrategy.NOT_CONFIGURED) {
43+
if (!context.settingsStore.disableSignatureVerification) {
4544
returnRowGroup(
4645
RowGroup.RowField(urlField),
4746
RowGroup.RowField(emptyLine),

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp