Skip to content

feat: Enforce strict crypto only: remove DisableWeakAlgorithms option#2

Merged
sks merged 13 commits intomainfrom
feature/remove_weak_algo
Feb 28, 2026
Merged

feat: Enforce strict crypto only: remove DisableWeakAlgorithms option#2
sks merged 13 commits intomainfrom
feature/remove_weak_algo

Conversation

@sks
Copy link
Contributor

@sks sks commented Feb 28, 2026

Summary

Remove the disable_weak_algorithms configuration option and make secure development the only mode. Weak algorithms (e.g. MD5, TLS < 1.2, weak ciphers) are always disabled; there is no way to enable them.

Changes

Security

  • pkg/security/crypto.go: Dropped DisableWeakAlgorithms from CryptoConfig. TLSConfig() always uses TLS 1.2+ and the strict cipher list.
  • pkg/security/config.go: Updated comment to state that weak algorithms are always disabled.

Encode tool

  • pkg/tools/encodetool: MD5 is always disabled. The encode tool no longer offers or accepts md5; requests for md5 return an error directing users to SHA-256. Removed crypto/md5 and the disableMD5 flag from the implementation.
  • pkg/tools/encodetool/provider.go: NewToolProvider still accepts CryptoConfig for API compatibility; behavior is always strict.

Config & docs

  • docs/js/config-builder.js: Removed the "Disable weak algorithms" toggle and all disable_weak_algorithms state/TOML/YAML handling.
  • config.toml.example: Removed the commented [security.crypto] / disable_weak_algorithms block; added a single line noting that weak algorithms are always disabled.
  • AGENTS.md: Updated the [crypto_keylength] rule and checklist so that weak algorithms are always disabled with no config option.

Behavior after this PR

  • TLS: Always TLS 1.2+ with the strict cipher list (no option to relax).
  • Encode tool: MD5 is never supported; md5 requests get a security-policy error and a hint to use SHA-256.
  • Config: No disable_weak_algorithms (or equivalent) anywhere; secure defaults are the only mode.

@github-advanced-security
Copy link

This pull request sets up GitHub code scanning for this repository. Once the scans have completed and the checks have passed, the analysis results for this pull request branch will appear on this overview. Once you merge this pull request, the 'Security' tab will show more code scanning analysis results (for example, for the default branch). Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results. For more information about GitHub code scanning, check out the documentation.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes the disable_weak_algorithms configuration knob and makes the project’s cryptographic posture strictly “secure-only” by default, ensuring weak algorithms (notably MD5) and legacy TLS settings cannot be re-enabled.

Changes:

  • Introduces a centralized security.CryptoConfig that always enforces TLS 1.2+ and a strict cipher policy.
  • Removes MD5 support from the encode tool (schema/docs + runtime behavior + tests).
  • Wires the strict TLS policy into outbound clients (HTTP via httputil, and IMAP via the email tool), and updates docs/examples accordingly.

Reviewed changes

Copilot reviewed 41 out of 42 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
pkg/tools/encodetool/provider.go Changes provider construction to accept security.CryptoConfig.
pkg/tools/encodetool/encodetool_test.go Updates tests to assert MD5 is rejected; adjusts provider construction.
pkg/tools/encodetool/encodetool.go Removes MD5 from supported ops/schema and rejects MD5 requests with a policy error.
pkg/tools/email/email.go Adds optional TLS config injection for IMAP and clones before dialing.
pkg/security/crypto.go Adds centralized crypto/TLS policy (TLSConfig, cipher suite list, NIST constants).
pkg/security/config.go Extends security config to include crypto policy alongside secrets config.
pkg/httputil/client.go Adds global default TLS config wiring for HTTP clients/transports.
pkg/app/app.go Applies the strict TLS config at bootstrap; wires IMAP TLS config and updated encode provider.
examples/ticket-to-pr/AGENTS.md Updates an architecture diagram (contains a new typo).
docs/js/config-builder.js Adjusts TOML emission logic for [security.secrets].
config.toml.example Updates security section comments to reflect secure-only crypto policy.
SECURITY.md Updates vulnerability handling expectations and adds delivery/crypto practice notes.
README.md Adds badges and formatting updates.
Agents.md Adds mandatory crypto policy rules/checklist entries referencing the new centralized policy.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@sks sks force-pushed the feature/remove_weak_algo branch from 0f0e542 to 7af932a Compare February 28, 2026 02:31
@sks
Copy link
Contributor Author

sks commented Feb 28, 2026

Addressed all Copilot review comments:

  1. AGENTS.md diagram — Updated "Load Agents.md agents person" to "Load Agents.md agent persona" (commit: 65696c8).
  2. CryptoConfig/TLSConfig tests — Added Describe("CryptoConfig") in pkg/security/security_test.go with specs for MinVersion TLS 1.2 and allowed TLS 1.2 ECDHE cipher suites.
  3. encodetool jsonschema — Removed trailing period from sha256. in the operation description.
  4. encodetool provider comment — Reworded to state CryptoConfig is passed for shared security policy; weak algorithms always disabled.
  5. httputil SetDefaultTLSConfig — Now clones the config before storing; doc updated.
  6. crypto cipher suites — Limited defaultSecureCipherSuites() to TLS 1.2 ECDHE suites; added comment that TLS 1.3 uses Go defaults.
  7. encodetool_test ctx — md5 It block now takes ctx context.Context and passes it to e.encode.

All review threads have been resolved.

Copilot AI review requested due to automatic review settings February 28, 2026 02:40
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 44 out of 45 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

pkg/httputil/client.go:40

  • GetClient() hard-codes a 10s http.Client.Timeout. Several callers in this PR (e.g., Ollama model pulls, webfetch) previously relied on longer timeouts or caller-provided context deadlines, so this fixed timeout can cause requests to be canceled prematurely. Consider adding a GetClientWithTimeout(timeout time.Duration, enhancers ...RequestEnhancer) (or an options struct) and/or setting Timeout: 0 by default and enforcing timeouts via context.WithTimeout at call sites that need a cap.
func GetClient(requestEnhancer ...RequestEnhancer) *http.Client {
	return &http.Client{
		Timeout:   time.Second * 10,
		Transport: NewRoundTripper(requestEnhancer...),
	}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 67 to 70
func newFetchTools() *fetchTools {
return &fetchTools{
client: &http.Client{
Timeout: defaultTimeout,
},
client: httputil.GetClient(),
}
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The package comment and defaultTimeout constant state a 30s HTTP timeout, but newFetchTools() now uses httputil.GetClient() which currently sets a 10s http.Client.Timeout. This makes the documented behavior incorrect and may cause premature timeouts on slower sites. Either restore a 30s timeout for this tool (e.g., a GetClientWithTimeout(defaultTimeout) helper) or enforce the 30s limit via context.WithTimeout inside fetch().

Copilot uses AI. Check for mistakes.
Comment on lines +102 to +106
// Use oauth2.NewClient so the client gets refreshed tokens from savingTS;
// wrap with httputil's round tripper for consistent TLS (NIST 2030).
baseTransport := httputil.NewRoundTripper()
client := &http.Client{Transport: &oauth2.Transport{Source: savingTS, Base: baseTransport}}
return client, nil
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says “Use oauth2.NewClient…”, but the code constructs &http.Client{Transport: &oauth2.Transport{...}} directly. This is misleading for future maintainers (especially around how token refresh is wired). Either update the comment to reflect the actual approach (oauth2.Transport with Base round tripper) or switch to oauth2.NewClient and then wrap/replace the transport as intended.

Copilot uses AI. Check for mistakes.
@sks sks force-pushed the feature/remove_weak_algo branch from c2201f4 to 2f62549 Compare February 28, 2026 02:53
@sks sks force-pushed the feature/remove_weak_algo branch from 2f62549 to 4788b56 Compare February 28, 2026 02:54
Copilot AI review requested due to automatic review settings February 28, 2026 02:54
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 44 out of 45 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

pkg/httputil/client.go:40

  • GetClient() always constructs a brand-new http.Client with a brand-new http.Transport. Several call sites invoke GetClient() per request (e.g. web search / model reachability), which defeats connection pooling/keep-alives and can increase resource usage under load. Consider making GetClient return a shared client (or at least a shared underlying Transport) and/or providing an option-based constructor so callers can reuse clients while still applying the default TLS policy.
func GetClient(requestEnhancer ...RequestEnhancer) *http.Client {
	return &http.Client{
		Timeout:   time.Second * 10,
		Transport: NewRoundTripper(requestEnhancer...),
	}

pkg/expert/modelprovider/ollama.go:105

  • httputil.GetClient() enforces a fixed 10s http.Client.Timeout, but PullModel is documented to take many minutes and relies on a long-lived context. With the current client, pulls will reliably fail after ~10s regardless of the context deadline. Consider using a client/transport without a hard timeout for this call (rely on the context), or extend httputil to support a caller-specified timeout and use a long timeout here.
	req.Header.Set("Content-Type", "application/json")
	// Pull can take many minutes for large models.
	client := &http.Client{Timeout: 15 * time.Minute}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +102 to +106
// Use oauth2.NewClient so the client gets refreshed tokens from savingTS;
// wrap with httputil's round tripper for consistent TLS (NIST 2030).
baseTransport := httputil.NewRoundTripper()
client := &http.Client{Transport: &oauth2.Transport{Source: savingTS, Base: baseTransport}}
return client, nil
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says “Use oauth2.NewClient…”, but the implementation builds &http.Client{Transport: &oauth2.Transport{...}} directly. Either switch to oauth2.NewClient(ctx, savingTS) (then wrap its transport) or adjust the comment so it accurately reflects the current approach.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings February 28, 2026 04:03
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 47 out of 48 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +33 to +35
client.Client = httputil.GetClient(func(req *http.Request) {
req.Header.Set("Authorization", "Bearer "+cfg.Token)
})
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switching Bitbucket’s underlying http.Client from a custom transport with no overall timeout to httputil.GetClient() introduces a fixed 10s http.Client.Timeout. SCM operations can legitimately exceed 10s on slower networks or large responses, so this may cause unexpected failures. Consider setting an explicit, more suitable timeout here (or none) while still using httputil.NewRoundTripper() for centralized TLS settings and the Authorization header enhancer.

Copilot uses AI. Check for mistakes.
Comment on lines +71 to 72
client := httputil.GetClient()
resp, err := client.Do(httpReq)
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

httputil.GetClient() constructs a new http.Client with a new http.Transport each time. Calling it on every search prevents connection reuse and can leak resources (transports keep idle goroutines/conns unless reused/closed). Consider storing a client on bingTool (created once in NewBingTool) and reusing it for all requests.

Copilot uses AI. Check for mistakes.
Comment on lines 33 to 39
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url+"/api/tags", nil)
if err != nil {
return false
}
client := &http.Client{Timeout: 2 * time.Second}
resp, err := client.Do(req)
resp, err := httputil.GetClient().Do(req)
if err != nil {
return false
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

httputil.GetClient() creates a new http.Client + http.Transport each call; using it inside OllamaReachable/ListModels prevents connection reuse and can leave idle transports around. Consider reusing a shared client (package-level or passed in) so repeated setup/health checks don’t allocate a new transport each time.

Copilot uses AI. Check for mistakes.
@sks sks merged commit df5b92a into main Feb 28, 2026
3 checks passed
@sks sks deleted the feature/remove_weak_algo branch February 28, 2026 04:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants