fix: Validate twingate.host against trusted controller domains#353
fix: Validate twingate.host against trusted controller domains#353minhtule wants to merge 4 commits into
twingate.host against trusted controller domains#353Conversation
twingate.host against trusted controller domains
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #353 +/- ##
==========================================
+ Coverage 86.07% 86.37% +0.29%
==========================================
Files 40 40
Lines 2830 2847 +17
==========================================
+ Hits 2436 2459 +23
+ Misses 269 264 -5
+ Partials 125 124 -1
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR tightens configuration security by validating twingate.host during config validation to ensure the controller JWKS trust anchor can only point at approved Twingate-owned domains.
Changes:
- Add
twingate.hosthostname validation and restrict it to trusted suffixes (twingate.com,opstg.com,test). - Extend
Config.Validate()to enforce the new host validation. - Add/adjust config validation tests to cover allowed and disallowed host values.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| internal/config/config.go | Adds host validation logic (regex + trusted suffix allowlist) and enforces it during config validation. |
| internal/config/config_test.go | Updates existing validation tests and adds new cases for allowed/disallowed twingate.host values. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| for domain := range IssuerByDomain { | ||
| if lowered == domain || strings.HasSuffix(lowered, "."+domain) { | ||
| return nil | ||
| } | ||
| } |
There was a problem hiding this comment.
.test is RFC 6761 non-routable/local-only. We don't need custom code for it.
| for domain, issuer := range config.IssuerByDomain { | ||
| if lowered == domain || strings.HasSuffix(lowered, "."+domain) { | ||
| return issuer | ||
| } | ||
| } |
There was a problem hiding this comment.
.test is RFC 6761 non-routable/local-only. We don't need custom code for it.
| "test": "twingate-local", | ||
| "dev.opstg.com": "twingate-dev", | ||
| "stg.opstg.com": "twingate-stg", | ||
| "sec.opstg.com": "twingate-sec", |
| { | ||
| name: "host with test suffix", | ||
| config: &Config{ | ||
| Twingate: TwingateConfig{Network: "test", Host: "acme.test"}, | ||
| Port: 8443, |
Related Tickets & Documents
Changes
twingate.networkis a single DNS label, since it is interpolated into the JWKS URL authority.twingate.hostagainst the trusted Twingate controller domains, matched case-insensitively, using the same allowlist as token issuer validation (single source of truth inconfig) so an accepted host always has a known JWT issuer.