Skip to content

fix(rpc): Use correct SDK endpoint for DID registration#33

Merged
beonde merged 4 commits intomainfrom
fix/did-registration-endpoint
Feb 17, 2026
Merged

fix(rpc): Use correct SDK endpoint for DID registration#33
beonde merged 4 commits intomainfrom
fix/did-registration-endpoint

Conversation

@beonde
Copy link
Member

@beonde beonde commented Feb 16, 2026

Summary

Fixes the DID registration endpoint in the SimpleGuard Init RPC to align with the server's SDK API.

Changes

internal/rpc/simpleguard_service.go

Before After
POST /v1/agents/{id}/dids PUT /v1/sdk/agents/{id}
Authorization: Bearer {key} X-Capiscio-Registry-Key: {key}
{"did": "...", "public_key": "..."} {"did": "..."}

Root Cause

The sidecar was calling a non-existent endpoint. The server's SDK routes use:

  • PUT /v1/sdk/agents/{id} for updating agent properties including DID
  • X-Capiscio-Registry-Key header for API key authentication

Related PRs

Testing

This change enables the full Let's Encrypt-style CapiscIO.connect() flow to work end-to-end with the live registry.

- Change endpoint from /v1/agents/{id}/dids to /v1/sdk/agents/{id}
- Change HTTP method from POST to PUT (update existing agent)
- Change auth header from Authorization: Bearer to X-Capiscio-Registry-Key
- Remove public_key from payload (not needed for DID update)

This aligns the core sidecar with the server's SDK API.
Copilot AI review requested due to automatic review settings February 16, 2026 22:16
@codecov
Copy link

codecov bot commented Feb 16, 2026

Codecov Report

❌ Patch coverage is 85.71429% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/rpc/simpleguard_service.go 85.71% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

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

Fixes the SimpleGuard Init DID registration call to use the server’s SDK update-agent endpoint and API-key header so the connect/init flow can successfully register an agent DID.

Changes:

  • Switch DID registration from POST /v1/agents/{id}/dids to PUT /v1/sdk/agents/{id}.
  • Use X-Capiscio-Registry-Key header instead of Authorization: Bearer.
  • Update request body to only include {"did": "..."}.

// Uses PUT /v1/sdk/agents/{id} to update the agent's DID.
func (s *SimpleGuardService) registerDIDWithServer(serverURL, apiKey, agentID, didKey string, publicKeyJWK []byte) error {
url := fmt.Sprintf("%s/v1/agents/%s/dids", serverURL, agentID)
url := fmt.Sprintf("%s/v1/sdk/agents/%s", serverURL, agentID)
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

serverURL is concatenated directly into the request URL; if callers provide a trailing slash (e.g. https://api.capisc.io/), this produces a double-slash path (//v1/...) which can trigger redirects or routing mismatches on some servers. Consider normalizing serverURL (trim trailing /) or building the URL with url.JoinPath.

Copilot uses AI. Check for mistakes.
Comment on lines +644 to +650
req, err := http.NewRequest(http.MethodPut, url, bytes.NewReader(body))
if err != nil {
return fmt.Errorf("failed to create request: %w", err)
}

req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", apiKey))
req.Header.Set("X-Capiscio-Registry-Key", apiKey)
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The DID registration flow changed (method/path/header/payload), but there’s no unit test coverage asserting the new PUT /v1/sdk/agents/{id} call and X-Capiscio-Registry-Key header. Add a test (likely via httptest.Server) that exercises Init (or registerDIDWithServer) and verifies the request method, path, header, and JSON body.

Copilot uses AI. Check for mistakes.

// registerDIDWithServer registers DID with the CapiscIO server.
// Uses PUT /v1/sdk/agents/{id} to update the agent's DID.
func (s *SimpleGuardService) registerDIDWithServer(serverURL, apiKey, agentID, didKey string, publicKeyJWK []byte) error {
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

publicKeyJWK is still part of the registerDIDWithServer signature (and is passed from Init), but it’s no longer used in the payload. This makes the call site misleading and can become lint noise if unparam is enabled later. Remove the parameter and the extra argument at the call site (or, if the server still needs the key in some form, include it explicitly in the request body).

Copilot uses AI. Check for mistakes.
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 1 out of 1 changed files in this pull request and generated 1 comment.


// registerDIDWithServer registers DID with the CapiscIO server.
// Uses PUT /v1/sdk/agents/{id} to update the agent's DID.
func (s *SimpleGuardService) registerDIDWithServer(serverURL, apiKey, agentID, didKey string, publicKeyJWK []byte) error {
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The publicKeyJWK parameter is no longer used in this function since the payload was updated to only include the DID. Consider removing this parameter from the function signature to avoid confusion and maintain a cleaner API.

Copilot uses AI. Check for mistakes.
- Remove unused publicKeyJWK parameter
- Normalize serverURL to prevent double-slash issues
- Use strings.TrimRight to handle trailing slashes
- Add tests for RPC registerDIDWithServer function
- Update CLI registerDID to use new SDK endpoint
- Update CLI tests for new endpoint pattern
- Tests cover: successful registration, URL normalization,
  server errors, unauthorized responses
Copilot AI review requested due to automatic review settings February 17, 2026 20:41
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 4 out of 4 changed files in this pull request and generated 3 comments.

Comment on lines 743 to 750
var gotMethod, gotPath, gotAPIKey string

server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
gotMethod = r.Method
gotPath = r.URL.Path
gotAPIKey = r.Header.Get("X-Capiscio-Registry-Key")
json.NewDecoder(r.Body).Decode(&received)
w.WriteHeader(http.StatusOK)
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

The test writes to shared variables (gotMethod/gotPath/gotAPIKey/received) from the httptest server handler goroutine and reads them back in the test goroutine without synchronization. This will trigger data races under go test -race. Prefer asserting inside the handler, or send the captured values back over a channel / protect with a mutex.

Copilot uses AI. Check for mistakes.
Comment on lines 169 to 172
func TestRegisterDID(t *testing.T) {
var received struct {
DID string `json:"did"`
PublicKey json.RawMessage `json:"public_key"`
DID string `json:"did"`
}
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

This test relies on the httptest handler mutating received (and then the main test goroutine asserting on it) without synchronization. Because handlers run in a separate goroutine, this is a data race under go test -race. Consider performing assertions inside the handler, or communicate the decoded body back via a channel/mutex.

Copilot uses AI. Check for mistakes.
Comment on lines 360 to 361
// Note: public key is no longer sent - server doesn't require it for SDK registration
_ = pub // Kept in signature for backward compatibility
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

registerDID no longer uses the pub argument, but it is still part of the (unexported) function signature and is manually discarded. Since this function is only used within this package/file, it would be clearer to remove the parameter and update the call sites instead of keeping an intentionally-unused argument.

Suggested change
// Note: public key is no longer sent - server doesn't require it for SDK registration
_ = pub // Kept in signature for backward compatibility
// Note: public key is no longer sent - server doesn't require it for SDK registration.
// The pub parameter is retained for backward compatibility and is currently unused.

Copilot uses AI. Check for mistakes.
- Fix race conditions in tests using channels for thread-safe communication
- Improve comment style for unused pub parameter per review suggestion
- Tests now pass with -race flag
@beonde beonde merged commit be5c73b into main Feb 17, 2026
3 checks passed
@beonde beonde deleted the fix/did-registration-endpoint branch February 17, 2026 22:40
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.

1 participant

Comments