Skip to content

Releases: microsoft/CCF

7.0.13

Choose a tag to compare

@github-actions github-actions released this 28 Aug 15:53
7f40acc

Changed

  • Governance endpoints now select the API implemented by the running CCF build when api-version is omitted or set to latest. GET /gov/api returns an auto-generated OpenAPI document for this moving API, while dated api-version values continue to return their frozen documents. (#8147)

Added

  • C++ endpoints can now use ccf::endpoints::Endpoint::add_openapi_response<Out>() to document additional HTTP responses in their generated OpenAPI schema without changing the endpoint's primary success response (#8115).
  • New ledger.max_transaction_size node configuration option (default 32MB), which caps the total serialised size of transactions written to the ledger. The limit covers the whole ledger entry: the fixed 8-byte ledger entry header, the ledger encryption header, public domain size field, public domain and encrypted private domain. It is checked before a transaction is applied, so an oversized transaction is now rejected with 413 Payload Too Large and error code TransactionTooLarge, and subsequent transactions are unaffected, where previously an excessively large transaction could terminate the node. Reserved internal signature transactions are exempt because they must fill their reserved ledger version. The limit applies only to newly serialised non-reserved transactions; deserialising existing entries (including during recovery), historical queries and snapshots are unaffected, so entries written under a larger or unset limit remain readable. It must be smaller than memory.max_msg_size by at least the ring-buffer range response overhead, which is validated at node startup and by --check (#7992).

Changed

  • ccf::SessionContext::caller_cert is now immutable, and its SHA-256 digest is cached per session to avoid repeated hashing during user and member certificate authentication (#8164).
  • Clang builds now enable compile-time thread safety analysis for CCF's annotated PAL mutexes and condition-variable waits, with reusable annotations available from ccf/ds/thread_safety.h (#8180).

Fixed

  • Nodes from the previous service are now removed during disaster recovery instead of being retained as retired entries in GET /node/network/nodes, and ledger_code.py reports their code identities as removed (#8177).
  • Fixed an edge case where a follower could incorrectly commit to an abandoned fork while synchronising with the leader, causing it to become unavailable (#8172).

7.0.12

Choose a tag to compare

@github-actions github-actions released this 07 Aug 17:21
7a7e5c1

Fixed

  • Joining or recovering nodes now ignore structurally invalid local snapshots and try an older snapshot instead of terminating during startup (#8124).

Dependencies

  • The Python ccf package now supports cryptography 50 and requires cwt 3.3.0 or later (#8118).

7.0.11

Choose a tag to compare

@github-actions github-actions released this 05 Aug 20:41
a55dee8

Added

  • Recovery can now use a COSE snapshot signed by an earlier service identity after one or more disaster recoveries. Before deserialising the snapshot, the node reads previous-service-identity endorsement candidates from the public ledger suffix, validates a complete chain against the operator-provided identity, and retains it only for the current recovery attempt. Invalid or incomplete endorsement chains fall back to full-ledger replay (#8092).

Fixed

  • Asynchronous ledger reads (used to serve committed entry ranges to the enclave) no longer access the host Ledger object after it has been destroyed during shutdown. The Ledger now waits for any in-flight read workers to finish, and workers that have not yet started skip accessing it, fixing a potential use-after-free on shutdown (#8003).

Changed

  • TLS handshakes now prefer hybrid post-quantum key exchange groups, in the order SecP384r1MLKEM1024, SecP256r1MLKEM768, X25519MLKEM768, when the linked crypto provider supports them. The P-521, P-384 and P-256 groups are retained as fallbacks (#8107).
  • ccf.cose.verify_receipt() has moved and been renamed to ccf.receipt.verify_cose(); the old name still works but is deprecated (#8109).

7.0.10

Choose a tag to compare

@github-actions github-actions released this 16 Jul 13:54
4926b85

Changed

  • ccf::http::ParsedQuery (in include/ccf/http_query.h), returned by ccf::http::parse_query(), is now a std::multimap<std::string, std::string, std::less<>> that owns its decoded keys and values, rather than a std::multimap<std::string_view, std::string_view> pointing into the source query string. Owned storage is required because each key and value is now URL-decoded individually after splitting, which produces bytes not present in the original query. Application code that consumed the previous std::string_view keys/values may need to be updated (#8024).
  • ccf::RpcContext::get_request_query() (C++) and request.query (JavaScript apps) now return the raw, still percent-encoded query string, instead of a whole-string URL-decoded copy. This is what allows escaped separators to be preserved. Callers must decode each parameter after splitting: use ccf::http::parse_query()/ccf::http::get_query_value() (C++) or parse_request_query() (JS), or ccf::http::decode_query_component() to decode a whole query string (#8024).

Fixed

  • HTTP query parameters are now split before URL-decoding, so escaped ampersands in query parameter names and values are preserved correctly (#8024).
  • HTTP messages (requests or replies) whose Content-Length header advertises a body larger than the configured maximum body size are now rejected as soon as the headers have been parsed, rather than after enough body chunks have been received to exceed the limit (#8045).
  • The thread-identifier helpers used by ccf/ds/logger.h (ccf::threading::get_current_thread_id, set_current_thread_id, and reset_thread_id_generator) have moved out of libccf into a new standalone ccf_threading static library, which find_package(ccf) exports automatically. This removes a long-standing implicit circular dependency (#7977).
  • Build-graph change for consumers that link CCF component libraries directly. ccfcrypto now links the new ccf_threading library, and ccf_tasks and ccf_kv link ccf_threading directly instead of ccfcrypto. Downstream targets that linked ccf_tasks or ccf_kv directly and relied on them transitively supplying CCF cryptography must now link ccfcrypto explicitly. Applications built with add_ccf_app (which link ccf and ccf_launcher) are unaffected (#7977).
  • As a temporary workaround for a Linux CIFS client kernel bug present in Confidential Azure Container Instances, uncommitted recovery ledger chunks are closed before their .recovery suffix is removed and reopened afterwards. This preserves the SMB write-caching lease on Azure Files, avoiding synchronous round trips for subsequent ledger writes. The workaround should be reverted once the Confidential Azure Container Instances platform upgrades to a kernel containing upstream fix 2c7d399e551c (#8072).

7.0.9

Choose a tag to compare

@github-actions github-actions released this 10 Jul 19:50
ed136a4

Fixed

  • Curl request bodies can now be replayed when following redirects or retrying authentication (#8052).

7.0.8

Choose a tag to compare

@github-actions github-actions released this 10 Jul 12:31
ecd8108

Changed

  • The node join protocol client now uses the curl multi singleton client (introduced in #7102) instead of the legacy enclave RPCSessions::create_client() HTTP client, matching the JWT refresh and snapshot-fetch clients. The service certificate remains the sole trust anchor for the join connection (the host certificate store is never consulted) (#8040).
  • Node joins now check the target RPC address against the target node's certificate SANs. TLS certificate hostname verification (CURLOPT_SSL_VERIFYHOST) is now enforced on the join connection: the host in join.target_rpc_address must be covered by one of the target node's certificate Subject Alternative Names (SANs), and a join to an address absent from the target's SANs is now rejected (the previous join client did not check the target certificate name at all). CCF derives node-certificate SANs from node_certificate.subject_alt_names, or by default from each RPC interface's published_address, so standard deployments are unaffected; operators that configure a bespoke join.target_rpc_address must ensure it is present in the target node's certificate SANs (#8040).

Removed

  • The unused enclave-side HTTP client infrastructure (RPCSessions::create_client, HTTPClientSession, HTTP2ClientSession, UnencryptedHTTPClientSession, and the ClientSession base) has been removed following the migration of the node join client to curl, completing the legacy HTTP client removal tracked in #7262 (#8040).

Fixed

  • A node joining or recovering from a stale snapshot no longer fails to bootstrap its network identity history when the local key-value store briefly exposes a previous service identity. The network identity subsystem now detects that the topmost endorsement is signed by a stale service identity and retries (unbounded, matching the other pre-bootstrap waits) until the committed ledger suffix is replayed and the local store reaches the current service identity. Each retry logs the topmost endorsement's txid and the mismatching public keys (the endorsement's signer and the expected current network identity), so an operator can diagnose a node that stays in this state (#8042).

7.0.7

Choose a tag to compare

@github-actions github-actions released this 07 Jul 17:43
623ce5a

Changed

  • JWT/JWK auto-refresh outbound HTTP fetches (OpenID metadata and JWKS) now use the curl multi singleton client introduced in #7102, replacing the previous RPCSessions::create_client() path. Connection and TLS failures are now counted in refresh failure metrics via send_refresh_jwt_keys_error(), improving observability of network-level refresh errors (#7989).
  • JWT/JWK auto-refresh now supports configuring the maximum response body size for fetched OpenID metadata and JWKS via the jwt.key_refresh_max_response_size node startup config setting (#7989).
  • Fatal task worker stack traces now use libbacktrace for improved function and source-location resolution. Building CCF now requires the libbacktrace development package, and the RPM development package depends on libbacktrace-static (#7721).

Fixed

  • Curl multi client shutdown now aborts queued async requests without performing network I/O, and curl response header capture now enforces default header size and count limits (#8005).
  • Changing recovery members or the recovery threshold, refreshing recovery shares, or rekeying the ledger while the service is recovering now correctly returns an error instead of appearing to succeed. These operations were always potentially unsafe because at-recovery ledger secrets cannot be rekeyed; services with custom constitutions should update their set_member, remove_member, set_recovery_threshold, trigger_recovery_shares_refresh, and trigger_ledger_rekey actions to reject them while recovering (#7980).

7.0.6

Choose a tag to compare

@github-actions github-actions released this 22 Jun 17:35
7e7a0b1

Added

  • Experimental support for IPv6. Node RPC and node-to-node interface hosts may now be specified as IPv6 literals in bracketed form (e.g. [::1]:8000), and addresses are consistently parsed, bound, connected (with fallback across mixed IPv4/IPv6 resolved addresses), serialised, and embedded in redirect URLs for IPv6 (#7671).

Fixed

  • Forwarded commands are no longer processed until the node is part of the network, matching the existing behaviour for other node-to-node messages. Previously a forwarded command could be executed while the node was in an earlier startup state, which could lead to undefined behaviour for some commands (#7936).

7.0.5

Choose a tag to compare

@github-actions github-actions released this 15 Jun 18:44
722bbe8

Changed

  • The default and minimal sample constitutions reject set_jwt_issuer proposals whose issuer is not an https:// URL with no query or fragment. Previously, any string was accepted when auto_refresh was false (#7924).
  • The default and minimal sample constitutions reject set_ca_cert_bundle proposals containing non-CA certificates or intermediate CA certificates; every certificate in the bundle must be a self-signed (root) CA (#7924).
  • The default and minimal sample constitutions validate every JWK in set_jwt_issuer and set_jwt_public_signing_keys proposals: n/e/x/y must be base64url-encoded, kty must match the supplied key material, kid must be unique within a key set, use (if present) must be "sig", and alg (if present) must match the key type and curve per RFC 7518 section 3.4 (RS256 for RSA; ES256/ES384/ES512 bound to P-256/P-384/P-521). RSA keys must be at least 2048 bits, and EC coordinates must use the full zero-padded length for their curve (RFC 7518 section 6.2.1.2). P-521 is now an accepted EC curve (#7924).
  • The default and minimal sample constitutions validate that set_member's encryption_pub_key, when present, is a well-formed RSA public key (#7924).

Security

  • Host-created files (ledger chunks, snapshots, PID file, and node certificate/key files) are now created with restrictive permissions (0600) instead of relying on the process umask. Existing deployments will not see existing files affected; only newly created files will have these restricted permissions (#7916).

Dependencies

  • Updated didx509cpp to 0.99.0 (#7943).

6.0.28

Choose a tag to compare

@github-actions github-actions released this 15 Jun 12:30
4b5bf5b

Fixed

  • Nodes started in recovery or join mode from a snapshot more recent than the latest ledger file now correctly resume writing from the snapshot boundary (#7901).