Skip to content

Release Go SDK v1.7.0 - #51

Merged
maksimu merged 1 commit into
masterfrom
release/sdk/golang/core/v1.7.0
May 8, 2026
Merged

Release Go SDK v1.7.0#51
maksimu merged 1 commit into
masterfrom
release/sdk/golang/core/v1.7.0

Conversation

@idimov-keeper

@idimov-keeper idimov-keeper commented Jun 30, 2025

Copy link
Copy Markdown
Collaborator

Summary

Release branch for v1.7.0 — adds HTTP proxy support, regional token parsing, Gov Cloud Dev environment support, security hardening for config file permissions, graceful handling of broken vault data, custom cache documentation, and CI/CD publish workflow.

Changes

New Features

  • Proxy support (KSM-532): Configure HTTP/HTTPS proxy via ClientOptions.ProxyUrl for network environments requiring intermediaries
  • Regional token parsing (KSM-565): Parse one-time tokens with region prefix (US:, EU:, AU:, GOV:, JP:, CA:) to automatically set the correct backend hostname
  • GraphSync links (KSM-626): Add GraphSync links support
  • File removal (KSM-632): Add LinksToRemove parameter for file removal operations
  • HTTP status codes in errors (KSM-665): Include HTTP status codes in error messages to improve debugging of API communication issues
  • Gov Cloud Dev key (KSM-745): Add transmission public key 18 for Gov Cloud Dev environment support
  • Custom cache docs and example (KSM-658): Document ICache interface with godoc and add a thread-safe in-memory TTL cache example in example/custom-cache/

Bug Fixes

  • Broken vault data (KSM-663): Handle broken records, files, and folders gracefully — SDK logs warnings and continues processing valid records instead of crashing
  • Notation with shortcuts (KSM-736): Fix notation lookup failure when a KSM application has access to both a record and its shortcut (duplicate UID error)
  • SetNotes behavior (KSM-583): Upgrade SetNotes from UPDATE to UPSERT — now creates the notes field if absent
  • RecordCreate.ToDict() missing custom key (KSM-826): ToDict() omitted the "custom" key when no custom fields were set; Commander and Vault always include "custom": [] and the backend expects it present
  • RecordField JSON serialization (KSM-860): Add json struct tags to RecordField so keys serialize lowercase ("type", "label", "value", "required") matching the KSM V3 API; fix NewRecordField to unwrap concrete slice types via reflection so values produce ["x"] instead of [["x"]]
  • Shared-folder flat records (KSM-756): Records in the flat records[] array with a folderUid were decrypted with the app key instead of the folder key, silently producing empty field values. SDK now looks up the folder in folders[] and decrypts with the correct folder key
  • Proxy env var fallback (KSM-912): getTransport used a bare &http.Transport{} when ProxyUrl was not set, leaving the Proxy field nil and silently ignoring HTTPS_PROXY/HTTP_PROXY env vars. Now uses http.ProxyFromEnvironment in the fallback path, matching http.DefaultTransport
  • Corrupted record decryption (KSM-911): NewRecordFromJson never returned nil on AES-GCM decryption failure — callers received empty record stubs. Fixed by returning nil on both failure paths: record key decryption and record data decryption
  • Folder key decryption stubs (KSM-913): NewFolderFromJson and NewKeeperFolder now return nil when folder key or name decryption fails instead of non-nil stubs; fixed latent nil-guard in core.go
  • File key decryption stubs (KSM-914): NewKeeperFileFromJson now returns nil when file key decryption fails; GetMeta() short-circuits on an empty key; GetFileData() logs the error on data decryption failure
  • App key decryption error (KSM-916): GetSecrets silently returned an empty record list when encryptedAppKey decryption failed in the just-bound flow (first call after token exchange). Now returns an error immediately
  • NewKeeperFolder JSON unmarshal stub (KSM-917): NewKeeperFolder returned a non-nil stub with Name = "" when CBC-decrypted folder name bytes failed json.Unmarshal; now returns nil, completing the nil-return contract KSM-913 established for the DecryptAesCbc failure path in the same function
  • DownloadFile write failure silent success (KSM-918): SaveFile returned true even when os.WriteFile failed — the write error was logged but the caller received a success signal. SaveFile, DownloadFileByTitle, and DownloadFile now return error so callers receive the failure reason
  • HTTP status code missing from JSON-error path (KSM-919): HandleHttpError now returns *KeeperHTTPError on all non-200 paths; the JSON-error path previously omitted the status code from err.Error() while the non-JSON path already included it. The POST Error: wrapper uses fmt.Errorf("POST Error: %w", err) to preserve the error chain for errors.As
  • Cache bypassed on network errors (KSM-921): PostQuery now consults ICache.GetCachedValue when PostFunction returns a transport-level error (DNS failure, connection refused, TLS error, timeout). Previously the cache-check was unreachable on the err != nil path, providing no resilience for the most common outage mode
  • RecordDict sync: Sync RecordDict to RawJson in InsertField and UpdateField operations
  • Go 1.16 compatibility: Replace strings.Cut() (Go 1.18+) with strings.SplitN() in regional token parsing

Maintenance

  • Deprecation cleanup (KSM-616): Remove ioutil dependency, raise minimum Go version to 1.16
  • Secure file permissions (KSM-701): Config files written with mode 0600 (owner read/write only) instead of 0666
  • CI matrix testing: Test against Go 1.16, 1.20, and 1.22 to catch version-specific compatibility issues early
  • Publish workflow: Automated release workflow with SBOM generation (Syft + Manifest Cyber) and multi-version validation; action versions bumped to checkout v6.0.2, setup-go v6.4.0, upload-artifact v7.0.1, download-artifact v8.0.1; job ordering corrected so tests run before SBOM; release target pinned to github.sha instead of master; --notes-file CHANGELOG.md replaces --generate-notes
  • CHANGELOG.md: Curated v1.7.0 release notes for the GitHub release page
  • Package godoc comment: Added // Package core... comment to core.go so pkg.go.dev indexes a package summary in search results
  • README updates: Features section, JP/CA hostname entries, proxy documentation, KSM-916 changelog entry
  • Version bump to 1.7.0 (client version 17.0.0)

Documentation and Examples

  • Custom cache example corrected (KSM-920): example/custom-cache/ rewritten to demonstrate offline-fallback semantics — the first call populates the cache; a second call against an unreachable host returns cached records via the KSM-921 fallback; after Purge() the network error surfaces. README and CHANGELOG updated to describe ICache as an offline resilience mechanism, not a request-rate limiter

Breaking Changes

Minimum Go version: Now requires Go 1.16+ (previously 1.14+). Update your go.mod:

go 1.16

Nil returns on decryption failure: The following functions previously returned non-nil empty stubs on decryption failure and now return nil. Callers that did not nil-check the return value will panic on dereference:

  • NewRecordFromJson (KSM-911)
  • NewFolderFromJson / NewKeeperFolder (KSM-913, KSM-917)
  • NewKeeperFileFromJson (KSM-914)
  • GetSecrets now returns an error (not nil-error + empty list) when app key decryption fails (KSM-916)

File download return type (KSM-918): SaveFile, DownloadFileByTitle, and DownloadFile now return error instead of bool. Update call sites that check the boolean return:

// before
if record.DownloadFileByTitle("cert.pem", "/tmp/cert.pem") {

// after
if err := record.DownloadFileByTitle("cert.pem", "/tmp/cert.pem"); err == nil {

HTTP error string format (KSM-919): err.Error() on the JSON-error path now includes HTTPStatus=N as a prefix (e.g. "POST Error: HTTPStatus=403 Error: access_denied, ..."). Code that string-matched the old format will no longer match. Migrate to errors.As:

var khe *core.KeeperHTTPError
if errors.As(err, &khe) {
    // khe.StatusCode, khe.ResultCode, khe.Message
}

Related Issues

Comment thread .github/workflows/publish.go.yml Fixed
Comment thread .github/workflows/publish.go.yml Fixed
Comment thread .github/workflows/publish.go.yml Fixed
Comment thread .github/workflows/publish.go.yml Fixed
Comment thread .github/workflows/publish.go.yml Fixed
Comment thread .github/workflows/publish.go.yml Fixed
BREAKING CHANGE: minimum Go version raised to 1.16 (was 1.14)

Security:
- KSM-701: write client-config.json with mode 0600
- KSM-745: add transmission public key #18 for Gov Cloud Dev

Bug fixes:
- KSM-736: deduplicate records to fix notation lookup with shortcuts
- KSM-663: handle broken records, files, and folders gracefully
- KSM-826: RecordCreate.ToDict() always emits "custom" key
- KSM-860: RecordField JSON struct tags + value unwrapping fix
- KSM-756: use folder key for flat records carrying folderUid
- KSM-912: use ProxyFromEnvironment when ProxyUrl is not set
- KSM-911: skip records on AES-GCM decryption failure (return nil)
- KSM-913: return nil from NewFolderFromJson on decryption failure
- KSM-914: return nil from NewKeeperFileFromJson on decryption failure
- KSM-916: return error on app key decryption failure in GetSecrets
- KSM-917: return nil from NewKeeperFolder on json.Unmarshal failure
- KSM-919: KeeperHTTPError typed error; HTTP status on JSON-error path
- KSM-921: consult cache on network-level errors in PostQuery

Features:
- KSM-565: parse KSM tokens with region prefix (US:, EU:, AU:, GOV:, JP:, CA:)
- KSM-532: HTTP proxy support via ClientOptions.ProxyUrl
- KSM-665: include HTTP status codes in error messages
- KSM-632: add links2Remove parameter for file removal
- KSM-626: add GraphSync links support
- KSM-583: upgrade SetNotes to UPSERT behavior
- KSM-920: custom-cache example demonstrating offline-fallback semantics

Technical:
- KSM-616: remove deprecated ioutil; raise minimum Go to 1.16
- KSM-658: ICache and IKeyValueStorage godoc; custom-cache example
- CI matrix: test Go 1.16.x, 1.20.x, 1.22.x
@stas-schaller
stas-schaller force-pushed the release/sdk/golang/core/v1.7.0 branch from f1d2ffc to 8644a49 Compare April 30, 2026 18:56
@maksimu
maksimu merged commit 836e324 into master May 8, 2026
17 checks passed
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.

4 participants