Detail Bug Report
https://app.detail.dev/org_bfc5015c-a884-452c-af11-b223af3a12fa/bugs/bug_4570642a-781f-487a-8a54-8e59db392206
Introduced in #962 by @martien-wdy on Jun 10, 2026
Summary
- Context: The
refreshCertsForAuth function re-issues mTLS certificates when they expire or need renewal, preserving identity fields from the server response.
- Bug: When creating a new
CertificateInfo after a successful refresh, the function fails to set AssetID from the server response. It copies OrganizationID and UserID from the existing cert, but omits AssetID entirely.
- Actual vs. expected: After refresh, asset-authenticated sessions have
AssetID=0 instead of the original asset ID, causing the XFCC identity header to be omitted from all subsequent cloud RPC calls.
- Impact: Asset-authenticated CLI sessions (those using
--api-key for local pki-core) lose their identity on the server after any certificate refresh, breaking cloud tunneling, device enrollment, and all cloud operations that depend on the XFCC header.
Code with Bug
// In refreshCertsForAuth, auth.go lines 575-583:
auth.Certificates = []config.CertificateInfo{
{
PemCertificate: cert.GetPemCertificate(),
PemCertificateChain: cert.GetPemCertificateChain(),
PemPrivateKey: newKeyPEM,
OrganizationID: existingCert.OrganizationID,
UserID: existingCert.UserID,
// BUG: AssetID is not set at all - neither from response nor existing cert // <-- BUG 🔴 drops asset identity after refresh
},
}
Explanation
certXFCC only emits an identity header when UserID != "" or AssetID != 0. After a refresh, the refreshed certificate is saved with AssetID=0, so certXFCC returns an empty string and cloudContext omits the XFCC headers. The refresh RPC itself succeeds because it runs using the pre-refresh cert (which still has AssetID); the breakage occurs on subsequent cloud RPC calls after the updated config is written.
Codebase Inconsistency
Initial asset login correctly reads AssetID from the server response, but refresh does not preserve/populate it:
certInfo := config.CertificateInfo{
PemCertificate: cert.GetPemCertificate(),
PemCertificateChain: cert.GetPemCertificateChain(),
PemPrivateKey: privateKeyPEM,
OrganizationID: int(issueResp.GetOrganizationId()),
AssetID: int(issueResp.GetAssetId()), // <-- expected identity handling
}
Recommended Fix
Populate identity fields from the RefreshCertificate response Certificate (preferred, consistent with login):
cert := refreshResp.GetCertificate()
// ...
auth.Certificates = []config.CertificateInfo{
{
PemCertificate: cert.GetPemCertificate(),
PemCertificateChain: cert.GetPemCertificateChain(),
PemPrivateKey: newKeyPEM,
OrganizationID: int(cert.GetOrganizationId()),
UserID: cert.GetUserId(),
AssetID: int(cert.GetAssetId()), // <-- FIX
},
}
History
This bug was introduced in commit 45aa4e9. The commit added AssetID to config.CertificateInfo and correctly populated it in performLocalLogin (for --api-key authentication), but failed to update refreshCertsForAuth to preserve or populate the AssetID field during certificate refresh.
Detail Bug Report
https://app.detail.dev/org_bfc5015c-a884-452c-af11-b223af3a12fa/bugs/bug_4570642a-781f-487a-8a54-8e59db392206
Introduced in #962 by @martien-wdy on Jun 10, 2026
Summary
refreshCertsForAuthfunction re-issues mTLS certificates when they expire or need renewal, preserving identity fields from the server response.CertificateInfoafter a successful refresh, the function fails to setAssetIDfrom the server response. It copiesOrganizationIDandUserIDfrom the existing cert, but omitsAssetIDentirely.AssetID=0instead of the original asset ID, causing the XFCC identity header to be omitted from all subsequent cloud RPC calls.--api-keyfor local pki-core) lose their identity on the server after any certificate refresh, breaking cloud tunneling, device enrollment, and all cloud operations that depend on the XFCC header.Code with Bug
Explanation
certXFCConly emits an identity header whenUserID != ""orAssetID != 0. After a refresh, the refreshed certificate is saved withAssetID=0, socertXFCCreturns an empty string andcloudContextomits the XFCC headers. The refresh RPC itself succeeds because it runs using the pre-refresh cert (which still hasAssetID); the breakage occurs on subsequent cloud RPC calls after the updated config is written.Codebase Inconsistency
Initial asset login correctly reads
AssetIDfrom the server response, but refresh does not preserve/populate it:Recommended Fix
Populate identity fields from the
RefreshCertificateresponseCertificate(preferred, consistent with login):History
This bug was introduced in commit 45aa4e9. The commit added
AssetIDtoconfig.CertificateInfoand correctly populated it inperformLocalLogin(for--api-keyauthentication), but failed to updaterefreshCertsForAuthto preserve or populate theAssetIDfield during certificate refresh.