Skip to content

feat: implement DNS namespace validation and remote URL uniqueness checks - #306

Merged
domdomegg merged 3 commits into
mainfrom
adamj/issue-180-namespace-validation
Aug 26, 2025
Merged

domdomegg merged 3 commits into
mainfrom
adamj/issue-180-namespace-validation

Conversation

@domdomegg

@domdomegg domdomegg commented Aug 26, 2025 •

Copy link
Copy Markdown
Member

Summary

  • Add reverse-DNS namespace format validation for server names (namespace/name)
  • Validate remote URLs match the DNS namespace derived from hostname
  • Prevent duplicate remote URLs across different servers
  • Support localhost/development URLs without namespace restrictions
  • Add comprehensive test coverage for validation logic
  • Update database layer to support remote_url filtering

Fixes #180 by ensuring proper namespace governance and preventing URL conflicts.

@domdomegg
domdomegg marked this pull request as draft August 26, 2025 14:10
@domdomegg
domdomegg force-pushed the adamj/issue-180-namespace-validation branch from 6d0abc3 to 1b3dcaa Compare August 26, 2025 14:50
…ecks

- Add DNS namespace validation for publisher domains
- Implement remote URL uniqueness checks to prevent duplicates
- Handle edge cases for null and non-array remotes in PostgreSQL queries
- Increase query limit for better conflict detection
- Update domain validation logic with proper 4xx error codes
- Add comprehensive test coverage for validation scenarios

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
@domdomegg
domdomegg force-pushed the adamj/issue-180-namespace-validation branch from a42d3de to 52d1443 Compare August 26, 2025 14:55
@domdomegg
domdomegg marked this pull request as ready for review August 26, 2025 14:58
@domdomegg

Copy link
Copy Markdown
Member Author

@claude please review

@claude

claude Bot commented Aug 26, 2025 •

Copy link
Copy Markdown
Contributor

Claude finished @domdomegg's task —— View job


Code Review: DNS Namespace Validation and Remote URL Uniqueness

Review Summary ✅

This is a well-implemented feature that adds important governance controls to the registry. The implementation is comprehensive, well-tested, and follows good architectural patterns.

Detailed Review Findings

Review Checklist

  • Analyze core validation logic in model.go
  • Review service layer changes
  • Check database implementation updates
  • Examine test coverage and edge cases
  • Review API handler modifications
  • Run linting and tests if available
  • Provide final review summary

✅ Strengths

1. Robust Validation Logic (internal/model/model.go:240-362)

  • Clean separation of concerns with dedicated validation functions
  • Proper handling of localhost/development URLs (lines 287-289, 307-310)
  • Comprehensive URL parsing with appropriate error handling
  • Smart reverse-DNS conversion logic that handles edge cases

2. Excellent Test Coverage (internal/model/model_test.go)

  • 254 lines of comprehensive test cases covering all validation scenarios
  • Edge cases well covered: localhost URLs, malformed URLs, subdomain validation
  • Clear test structure with descriptive names and expected error messages
  • Good balance of positive and negative test cases

3. Clean Service Integration (internal/service/registry_service.go:88-95)

  • Validation cleanly integrated into the publish workflow
  • Proper error propagation and handling
  • New validateNoDuplicateRemoteURLs method with efficient database queries

4. Database Layer Enhancement (internal/database/memory.go:92-104, internal/database/postgres.go:79-83)

  • Added remote_url filter support in both memory and PostgreSQL implementations
  • Efficient filtering using JSONB queries in PostgreSQL
  • Consistent implementation across both database backends

🔍 Technical Observations

Security Considerations:

  • URL parsing uses Go's standard url.Parse which handles malicious URLs safely
  • No injection vulnerabilities found in database queries
  • Proper input validation before database operations

Performance Notes:

  • Remote URL conflict check queries up to 1000 servers (line 178) - reasonable limit
  • Database queries use proper indexing strategies
  • Memory implementation uses efficient map lookups

Error Handling:

  • Clear, actionable error messages for validation failures
  • Proper error wrapping and context preservation
  • Good separation between validation errors and system errors

📝 Minor Suggestions

  1. Consider Rate Limiting: The duplicate URL check could be expensive for servers with many remotes. Consider adding some basic rate limiting if this becomes an issue.

  2. Documentation: The validation logic is well-commented, but consider adding a brief overview comment at the top of the validation functions explaining the namespace governance approach.

  3. Future Enhancement: The current implementation doesn't validate TLD existence, which might be worth considering for production use.

🧪 Test Quality

  • Unit tests cover all major code paths
  • Integration tests verify end-to-end functionality
  • Mock usage is appropriate and well-structured
  • Tests run successfully with 93.8% coverage on handlers

⚠️ Notes

  • Linting failed due to missing golangci-lint installation, but code structure and style appear consistent with project standards
  • All unit tests pass successfully
  • No security vulnerabilities identified in the validation logic

Overall Assessment: This is a solid implementation that addresses issue #180 comprehensively. The code is production-ready with excellent test coverage and proper error handling. The namespace governance feature will effectively prevent URL conflicts while maintaining flexibility for development use cases.


Comment thread internal/model/model.go Resolved
Comment thread internal/model/model.go Resolved
for _, remote := range serverDetail.Remotes {
// Use filter to find servers with this remote URL
filter := map[string]any{
"remote_url": remote.URL,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Would it make sense to add name to the filter here?

Suggested change
"remote_url": remote.URL,
"remote_url": remote.URL,
"name": serverDetail.Name

Just trying to understand if we can move the "Check if any conflicting server has a different name" to the db query level and if it makes sense.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think it's not possible (with our current filtering) to filter for the name not being a particular value unfortunately.

@domdomegg
domdomegg merged commit 923b2e0 into main Aug 26, 2025
@domdomegg
domdomegg deleted the adamj/issue-180-namespace-validation branch August 26, 2025 22:03
rdimitrov added a commit that referenced this pull request Nov 6, 2026
A publisher can currently block an endpoint's operator from listing it
under their own namespace simply by registering the remote URL first.
The registry authenticates namespaces but does not verify remote URL
ownership, so registration order cannot establish the canonical
publisher.

This change allows different server names to reference the same remote
URL on both `/v0` and `/v0.1`. It removes the conflict check from
publication, admin metadata edits, single-version restores, and
all-version restores. Namespace authorization, URL validation,
name/version uniqueness, and per-name version history remain intact.
Existing records, response schemas, and database indexes are unchanged;
no data migration is needed. The existing `remotes_ms` log field is
retained at zero.

The original uniqueness rule accompanied namespace/hostname matching in
#180 and #306; #769 later removed hostname matching.

## Downstream compatibility

This changes a previously documented behavioral guarantee, even though
the API shape is unchanged. Consumers that use a remote URL as a unique
key, or resolve it to a single canonical listing, must support multiple
matching server names. Records should be keyed by name/version (and
registry when combining sources), with each listing's metadata, headers,
and template variables kept separate. A shared endpoint does not
establish publisher ownership or endorsement.

The publishing guide and changelog explain this change. Review the
compatibility implications and coordinate rollout with downstream
consumers. Re-enabling uniqueness after shared URLs have been accepted
could block those servers' subsequent publications, edits, and restores.
Discovery grouping and endpoint ownership verification are outside this
PR.

## Validation

Updates the indirect `github.com/klauspost/compress` dependency from
v1.20.1 to v1.20.2 to fix GO-2026-6865, which was reported by CI's
vulnerability scan. Local `govulncheck ./...` and the CI vulnerability
scan pass with the update.

- Added database-backed regressions for independent metadata, version
histories, latest-only pagination, encoded listings, admin edits, and
single/all-version restores to active or deprecated.
- Added HTTP publish coverage on both API versions proving shared URLs
succeed while unauthorized namespaces, duplicate name/version pairs, and
invalid remote URLs still fail.
- Confirmed the new publication, edit, and active-restore regressions
fail against the original service implementation and pass with this
change.
- Passed `go test -race -coverprofile=coverage.out -covermode=atomic
./internal/... ./cmd/...` using an isolated local PostgreSQL 17
instance.
- Passed `make lint` with golangci-lint v2.14.0, `make validate build`,
and `git diff --check`.
- CI passed all checks, including `make test-all` (with Docker/ko
integration tests), build/lint/validation, vulnerability scanning, and
CodeQL. The Docker/ko integration harness was not run locally.

---------

Co-authored-by: Copilot Autofix powered by AI <[email protected]>
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.

Enforce requirement: remote URL's in official registry must match reverse-DNS namespace

2 participants