From ccf21db2d2ec160d9a2b1c0ff2ae44bb0562bd8c Mon Sep 17 00:00:00 2001 From: Eddy Ashton Date: Thu, 11 Jul 2024 10:15:22 +0100 Subject: [PATCH] Add gov API version 2024-07-01 (#6321) --- CHANGELOG.md | 2 + CMakeLists.txt | 29 +- doc/build_apps/run_app.rst | 2 +- doc/governance/accept_recovery.rst | 10 +- doc/governance/adding_member.rst | 6 +- doc/governance/common_member_operations.rst | 6 +- .../gov_api_schemas/2023-06-01-preview.rst | 2 +- doc/governance/gov_api_schemas/2024-07-01.rst | 8 + doc/governance/gov_api_schemas/classic.rst | 4 +- doc/governance/hsm_keys.rst | 2 +- doc/governance/member_rpc_api.rst | 1 + doc/governance/open_network.rst | 8 +- doc/governance/proposals.rst | 12 +- .../examples/Ballots_Get.json | 0 .../examples/Ballots_Submit.json | 0 .../examples/EncryptedShares_Get.json | 0 .../examples/Proposals_Create.json | 0 .../examples/Proposals_Get.json | 0 .../examples/Proposals_GetActions.json | 0 .../examples/Proposals_List.json | 0 .../examples/Proposals_Withdraw.json | 0 .../ServiceState_GetConstitution.json | 0 .../ServiceState_GetJoinPolicies.json | 2 +- .../examples/ServiceState_GetJsApp.json | 0 .../examples/ServiceState_GetJwkInfo.json | 29 + .../examples/ServiceState_GetMember.json | 0 .../examples/ServiceState_GetNode.json | 29 + .../examples/ServiceState_GetServiceInfo.json | 0 .../examples/ServiceState_ListMembers.json | 0 .../examples/ServiceState_ListNodes.json | 50 + .../examples/Shares_Submit.json | 0 .../examples/StateDigests_Acknowledge.json | 0 .../examples/StateDigests_Get.json | 0 .../examples/StateDigests_Update.json | 2 +- .../examples/Transactions_Get.json | 0 .../examples/Transactions_GetCommit.json | 0 .../2023-06-01-preview/gov.json} | 70 +- .../gov/2024-07-01/examples/Ballots_Get.json | 16 + .../2024-07-01/examples/Ballots_Submit.json | 24 + .../examples/EncryptedShares_Get.json | 15 + .../2024-07-01/examples/Proposals_Create.json | 19 + .../2024-07-01/examples/Proposals_Get.json | 22 + .../examples/Proposals_GetActions.json | 23 + .../2024-07-01/examples/Proposals_List.json | 26 + .../examples/Proposals_Withdraw.json | 23 + .../ServiceState_GetConstitution.json | 14 + .../ServiceState_GetJoinPolicies.json | 33 + .../examples/ServiceState_GetJsApp.json | 27 + .../examples/ServiceState_GetJwkInfo.json | 2 +- .../examples/ServiceState_GetMember.json | 17 + .../examples/ServiceState_GetNode.json | 2 +- .../examples/ServiceState_GetServiceInfo.json | 22 + .../examples/ServiceState_ListMembers.json | 31 + .../examples/ServiceState_ListNodes.json | 2 +- .../2024-07-01/examples/Shares_Submit.json | 18 + .../examples/StateDigests_Acknowledge.json | 12 + .../2024-07-01/examples/StateDigests_Get.json | 16 + .../examples/StateDigests_Update.json | 17 + .../2024-07-01/examples/Transactions_Get.json | 15 + .../examples/Transactions_GetCommit.json | 15 + doc/schemas/gov/2024-07-01/gov.json | 2455 +++++++++++++++++ src/node/gov/api_schema.h.in | 3 + src/node/gov/api_version.h | 56 +- src/node/gov/gov_endpoint_registry.h | 22 +- src/node/gov/handlers/acks.h | 3 + src/node/gov/handlers/proposals.h | 7 + src/node/gov/handlers/recovery.h | 2 + src/node/gov/handlers/service_state.h | 114 +- src/node/gov/handlers/transactions.h | 2 + tests/infra/clients.py | 8 +- tests/infra/consortium.py | 1 + tests/infra/e2e_args.py | 2 +- tests/infra/member.py | 10 +- tests/js-modules/modules.py | 37 + tests/schema.py | 58 +- 75 files changed, 3370 insertions(+), 95 deletions(-) create mode 100644 doc/governance/gov_api_schemas/2024-07-01.rst rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/Ballots_Get.json (100%) rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/Ballots_Submit.json (100%) rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/EncryptedShares_Get.json (100%) rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/Proposals_Create.json (100%) rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/Proposals_Get.json (100%) rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/Proposals_GetActions.json (100%) rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/Proposals_List.json (100%) rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/Proposals_Withdraw.json (100%) rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/ServiceState_GetConstitution.json (100%) rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/ServiceState_GetJoinPolicies.json (99%) rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/ServiceState_GetJsApp.json (100%) create mode 100644 doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetJwkInfo.json rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/ServiceState_GetMember.json (100%) create mode 100644 doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetNode.json rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/ServiceState_GetServiceInfo.json (100%) rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/ServiceState_ListMembers.json (100%) create mode 100644 doc/schemas/gov/2023-06-01-preview/examples/ServiceState_ListNodes.json rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/Shares_Submit.json (100%) rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/StateDigests_Acknowledge.json (100%) rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/StateDigests_Get.json (100%) rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/StateDigests_Update.json (99%) rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/Transactions_Get.json (100%) rename doc/schemas/{mccf => gov}/2023-06-01-preview/examples/Transactions_GetCommit.json (100%) rename doc/schemas/{mccf/2023-06-01-preview/mccfgov.json => gov/2023-06-01-preview/gov.json} (97%) create mode 100644 doc/schemas/gov/2024-07-01/examples/Ballots_Get.json create mode 100644 doc/schemas/gov/2024-07-01/examples/Ballots_Submit.json create mode 100644 doc/schemas/gov/2024-07-01/examples/EncryptedShares_Get.json create mode 100644 doc/schemas/gov/2024-07-01/examples/Proposals_Create.json create mode 100644 doc/schemas/gov/2024-07-01/examples/Proposals_Get.json create mode 100644 doc/schemas/gov/2024-07-01/examples/Proposals_GetActions.json create mode 100644 doc/schemas/gov/2024-07-01/examples/Proposals_List.json create mode 100644 doc/schemas/gov/2024-07-01/examples/Proposals_Withdraw.json create mode 100644 doc/schemas/gov/2024-07-01/examples/ServiceState_GetConstitution.json create mode 100644 doc/schemas/gov/2024-07-01/examples/ServiceState_GetJoinPolicies.json create mode 100644 doc/schemas/gov/2024-07-01/examples/ServiceState_GetJsApp.json rename doc/schemas/{mccf/2023-06-01-preview => gov/2024-07-01}/examples/ServiceState_GetJwkInfo.json (92%) create mode 100644 doc/schemas/gov/2024-07-01/examples/ServiceState_GetMember.json rename doc/schemas/{mccf/2023-06-01-preview => gov/2024-07-01}/examples/ServiceState_GetNode.json (97%) create mode 100644 doc/schemas/gov/2024-07-01/examples/ServiceState_GetServiceInfo.json create mode 100644 doc/schemas/gov/2024-07-01/examples/ServiceState_ListMembers.json rename doc/schemas/{mccf/2023-06-01-preview => gov/2024-07-01}/examples/ServiceState_ListNodes.json (98%) create mode 100644 doc/schemas/gov/2024-07-01/examples/Shares_Submit.json create mode 100644 doc/schemas/gov/2024-07-01/examples/StateDigests_Acknowledge.json create mode 100644 doc/schemas/gov/2024-07-01/examples/StateDigests_Get.json create mode 100644 doc/schemas/gov/2024-07-01/examples/StateDigests_Update.json create mode 100644 doc/schemas/gov/2024-07-01/examples/Transactions_Get.json create mode 100644 doc/schemas/gov/2024-07-01/examples/Transactions_GetCommit.json create mode 100644 doc/schemas/gov/2024-07-01/gov.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cb02b6fa11..870628f8a56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Added - The `cchost` configuration file now includes an `idle_connection_timeout` option. This controls how long the node will keep idle connections (for user TLS sessions) before automatically closing them. This may be set to `null` to restore the previous behaviour, where idle connections are never closed. By default connections will be closed after 60s of idle time. +- New endpoints `GET /gov/service/javascript-modules` and `GET /gov/service/javascript-modules/{moduleName}` to retrieve the raw JS code of the currently installed app. Note that the `{moduleName}` path parameter will need to be URL-encoded to escape any `/` characters (eg - `/foo/bar.js` should become `%2Ffoo%2Fbar.js`). +- New gov API version `2024-07-01`. This is near-identical to `2023-06-01-preview`, but additionally offers the new `javascript-modules` endpoints. ### Changed diff --git a/CMakeLists.txt b/CMakeLists.txt index ebd4cf84f51..a96ccf98b15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -577,14 +577,23 @@ configure_file( @ONLY ) -file(READ ${CCF_DIR}/doc/schemas/mccf/2023-06-01-preview/mccfgov.json +file(READ ${CCF_DIR}/doc/schemas/gov/2023-06-01-preview/gov.json GOV_API_SCHEMA_2023_06_01_PREVIEW ) set_property( DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS - ${CCF_DIR}/doc/schemas/mccf/2023-06-01-preview/mccfgov.json + ${CCF_DIR}/doc/schemas/gov/2023-06-01-preview/gov.json +) +file(READ ${CCF_DIR}/doc/schemas/gov/2024-07-01/gov.json + GOV_API_SCHEMA_2024_07_01 +) +set_property( + DIRECTORY + APPEND + PROPERTY CMAKE_CONFIGURE_DEPENDS + ${CCF_DIR}/doc/schemas/gov/2024-07-01/gov.json ) configure_file( ${CCF_DIR}/src/node/gov/api_schema.h.in ${CCF_DIR}/src/node/gov/api_schema.h @@ -1160,19 +1169,19 @@ if(BUILD_TESTS) if(LONG_TESTS) set(ADDITIONAL_RECOVERY_ARGS --with-load) - endif() - add_e2e_test( - NAME recovery_test_cft_api_0 - PYTHON_SCRIPT ${CMAKE_SOURCE_DIR}/tests/recovery.py - ADDITIONAL_ARGS ${ADDITIONAL_RECOVERY_ARGS} --gov-api-version "classic" - ) + add_e2e_test( + NAME recovery_test_cft_api_0 + PYTHON_SCRIPT ${CMAKE_SOURCE_DIR}/tests/recovery.py + ADDITIONAL_ARGS ${ADDITIONAL_RECOVERY_ARGS} --gov-api-version "classic" + ) + endif() add_e2e_test( NAME recovery_test_cft_api_1 PYTHON_SCRIPT ${CMAKE_SOURCE_DIR}/tests/recovery.py ADDITIONAL_ARGS ${ADDITIONAL_RECOVERY_ARGS} --gov-api-version - "2023-06-01-preview" + "2024-07-01" ) add_e2e_test( @@ -1384,7 +1393,7 @@ if(BUILD_TESTS) add_e2e_test( NAME membership_api_1 PYTHON_SCRIPT ${CMAKE_SOURCE_DIR}/tests/membership.py - ADDITIONAL_ARGS --gov-api-version "2023-06-01-preview" + ADDITIONAL_ARGS --gov-api-version "2024-07-01" ) set(PARTITIONS_TEST_ARGS diff --git a/doc/build_apps/run_app.rst b/doc/build_apps/run_app.rst index 7477035fd1a..35f7f7568b4 100644 --- a/doc/build_apps/run_app.rst +++ b/doc/build_apps/run_app.rst @@ -91,7 +91,7 @@ This should look much like a standard HTTP server, with error codes for missing $ curl https://127.0.0.1:8000/app/not/a/real/resource -X GET --cacert service_cert.pem --cert user0_cert.pem --key user0_privk.pem -i HTTP/1.1 404 Not Found - $ curl https://127.0.0.1:8000/gov/members/proposals:create?api-version=2023-06-01-preview -X POST --cacert service_cert.pem --cert user0_cert.pem --key user0_privk.pem -i + $ curl https://127.0.0.1:8000/gov/members/proposals:create?api-version=2024-07-01 -X POST --cacert service_cert.pem --cert user0_cert.pem --key user0_privk.pem -i HTTP/1.1 403 Forbidden Logging App Commands diff --git a/doc/governance/accept_recovery.rst b/doc/governance/accept_recovery.rst index 39f49aca16f..8b4edb40621 100644 --- a/doc/governance/accept_recovery.rst +++ b/doc/governance/accept_recovery.rst @@ -35,7 +35,7 @@ A member proposes to recover the network and other members can vote on the propo --signing-key member1_privk.pem \ --signing-cert member1_cert.pem \ --content transition_service_to_open.json \ - | curl https:///gov/members/proposals:create?api-version=2023-06-01-preview \ + | curl https:///gov/members/proposals:create?api-version=2024-07-01 \ --cacert service_cert.pem \ --data-binary @- \ -H "content-type: application/cose" @@ -53,7 +53,7 @@ A member proposes to recover the network and other members can vote on the propo --signing-key member1_privk.pem \ --signing-cert member1_cert.pem \ --content vote_accept.json \ - | curl https:///gov/members/proposals/1b7cae1585077104e99e1860ad740efe28ebd498dbf9988e0e7b299e720c5377/ballots/d5d7d5fed6f839028456641ad5c3df18ce963bd329bd8a21df16ccdbdbba1eb1:submit?api-version=2023-06-01-preview \ + | curl https:///gov/members/proposals/1b7cae1585077104e99e1860ad740efe28ebd498dbf9988e0e7b299e720c5377/ballots/d5d7d5fed6f839028456641ad5c3df18ce963bd329bd8a21df16ccdbdbba1eb1:submit?api-version=2024-07-01 \ --cacert service_cert.pem \ --data-binary @- \ -H "content-type: application/cose" @@ -71,7 +71,7 @@ A member proposes to recover the network and other members can vote on the propo --signing-key member2_privk.pem \ --signing-cert member2_cert.pem \ --content vote_accept.json - | curl https:///gov/members/proposals/1b7cae1585077104e99e1860ad740efe28ebd498dbf9988e0e7b299e720c5377/ballots/e306e3a6eead2f4a3854302b41c3015bf12db9535ac0be1b8cf6584f84bca92b:submit?api-version=2023-06-01-preview \ + | curl https:///gov/members/proposals/1b7cae1585077104e99e1860ad740efe28ebd498dbf9988e0e7b299e720c5377/ballots/e306e3a6eead2f4a3854302b41c3015bf12db9535ac0be1b8cf6584f84bca92b:submit?api-version=2024-07-01 \ --cacert service_cert.pem \ --data-binary @- \ -H "content-type: application/cose" @@ -104,7 +104,7 @@ The recovery share retrieval, decryption and submission steps can be convenientl $ submit_recovery_share.sh https:// \ --member-enc-privk member0_enc_privk.pem \ --cert member0_cert.pem \ - --api-version 2023-06-01-preview \ + --api-version 2024-07-01 \ --key member0_privk.pem \ --cacert service_cert.pem HTTP/1.1 200 OK @@ -115,7 +115,7 @@ The recovery share retrieval, decryption and submission steps can be convenientl $ submit_recovery_share.sh https:// \ --member-enc-privk member1_enc_privk.pem \ --cert member1_cert.pem \ - --api-version 2023-06-01-preview \ + --api-version 2024-07-01 \ --key member1_privk.pem \ --cacert service_cert.pem HTTP/1.1 200 OK diff --git a/doc/governance/adding_member.rst b/doc/governance/adding_member.rst index 24cf1b32478..e6c22acf4e8 100644 --- a/doc/governance/adding_member.rst +++ b/doc/governance/adding_member.rst @@ -64,7 +64,7 @@ First, the new member should update and retrieve the latest state digest via the --signing-key new_member_privk.pem \ --signing-cert new_member_cert.pem \ --content empty_file \ # Note that passing an empty file is required - | curl https:///gov/members/state-digests/7f46110b62ccbbd5f18b4c9bda876024399fd538133f8c26d4bfe5a9d80e59e6:update?api-version=2023-06-01-preview \ + | curl https:///gov/members/state-digests/7f46110b62ccbbd5f18b4c9bda876024399fd538133f8c26d4bfe5a9d80e59e6:update?api-version=2024-07-01 \ -X POST \ --cacert service_cert.pem \ --key new_member_privk.pem \ @@ -86,7 +86,7 @@ Then, the new member should sign the state digest returned by :http:POST:`/gov/m --signing-key new_member_privk.pem \ --signing-cert new_member_cert.pem \ --content request.json \ - | curl https:///gov/members/state-digests/7f46110b62ccbbd5f18b4c9bda876024399fd538133f8c26d4bfe5a9d80e59e6:ack?api-version=2023-06-01-preview \ + | curl https:///gov/members/state-digests/7f46110b62ccbbd5f18b4c9bda876024399fd538133f8c26d4bfe5a9d80e59e6:ack?api-version=2024-07-01 \ --cacert service_cert.pem \ --data-binary @- \ -H "content-type: application/cose" @@ -95,7 +95,7 @@ Once the command completes, the new member becomes active and can take part in g .. code-block:: bash - $ curl https:///gov/service/members/7f46110b62ccbbd5f18b4c9bda876024399fd538133f8c26d4bfe5a9d80e59e6?api-version=2023-06-01-preview?api-version=2023-06-01-preview --silent | jq + $ curl https:///gov/service/members/7f46110b62ccbbd5f18b4c9bda876024399fd538133f8c26d4bfe5a9d80e59e6?api-version=2024-07-01 --silent | jq { "memberId": "7f46110b62ccbbd5f18b4c9bda876024399fd538133f8c26d4bfe5a9d80e59e6", "certificate": <...>, diff --git a/doc/governance/common_member_operations.rst b/doc/governance/common_member_operations.rst index 153b155eed6..814404545fb 100644 --- a/doc/governance/common_member_operations.rst +++ b/doc/governance/common_member_operations.rst @@ -61,7 +61,7 @@ To limit the scope of key compromise, members of the consortium can refresh the --signing-key member1_privk.pem \ --signing-cert member1_cert.pem \ --content trigger_ledger_rekey.json \ - | curl https:///gov/members/proposals:create?api-version=2023-06-01-preview \ + | curl https:///gov/members/proposals:create?api-version=2024-07-01 \ --cacert service_cert.pem \ --data-binary @- \ -H "content-type: application/cose" @@ -79,7 +79,7 @@ To limit the scope of key compromise, members of the consortium can refresh the --signing-key member2_privk.pem \ --signing-cert member2_cert.pem \ --content vote_accept_1.json \ - | curl https:///gov/members/proposals/2f739d154b8cddacd7fc6d03cc8d4d20626e477ec4b1af10a74c670bb38bed5e/ballots/fe6ed012e8184f28afb48d0d58dca7f461dc997c43179acf97362dc0b76ddeb7:submit?api-version=2023-06-01-preview \ + | curl https:///gov/members/proposals/2f739d154b8cddacd7fc6d03cc8d4d20626e477ec4b1af10a74c670bb38bed5e/ballots/fe6ed012e8184f28afb48d0d58dca7f461dc997c43179acf97362dc0b76ddeb7:submit?api-version=2024-07-01 \ --cacert service_cert.pem \ --data-binary @- \ -H "content-type: application/cose" @@ -97,7 +97,7 @@ To limit the scope of key compromise, members of the consortium can refresh the --signing-key member3_privk.pem \ --signing-cert member3_cert.pem \ --content vote_accept_1.json \ - | curl https:///gov/members/proposals/2f739d154b8cddacd7fc6d03cc8d4d20626e477ec4b1af10a74c670bb38bed5e/ballots/75b86775f1253c308f4e9aeddf912d40b8d77db9eaa9a0f0026f581920d5e9b8:submit?api-version=2023-06-01-preview \ + | curl https:///gov/members/proposals/2f739d154b8cddacd7fc6d03cc8d4d20626e477ec4b1af10a74c670bb38bed5e/ballots/75b86775f1253c308f4e9aeddf912d40b8d77db9eaa9a0f0026f581920d5e9b8:submit?api-version=2024-07-01 \ --cacert service_cert.pem \ --data-binary @- \ -H "content-type: application/cose" diff --git a/doc/governance/gov_api_schemas/2023-06-01-preview.rst b/doc/governance/gov_api_schemas/2023-06-01-preview.rst index be652560ed0..4f1028c8001 100644 --- a/doc/governance/gov_api_schemas/2023-06-01-preview.rst +++ b/doc/governance/gov_api_schemas/2023-06-01-preview.rst @@ -5,5 +5,5 @@ This API is available by passing the query parameter ``api-version=2023-06-01-pr This is available from CCF 5.0.0-dev3. -.. openapi:: ../../schemas/mccf/2023-06-01-preview/mccfgov.json +.. openapi:: ../../schemas/gov/2023-06-01-preview/gov.json \ No newline at end of file diff --git a/doc/governance/gov_api_schemas/2024-07-01.rst b/doc/governance/gov_api_schemas/2024-07-01.rst new file mode 100644 index 00000000000..b4f593c321e --- /dev/null +++ b/doc/governance/gov_api_schemas/2024-07-01.rst @@ -0,0 +1,8 @@ +2024-07-01 +========== + +This API is available by passing the query parameter ``api-version=2024-07-01`` to endpoints under the ``/gov`` prefix. + +This is available from CCF 5.0.0-rc1. + +.. openapi:: ../../schemas/gov/2024-07-01/gov.json diff --git a/doc/governance/gov_api_schemas/classic.rst b/doc/governance/gov_api_schemas/classic.rst index 34d1387a7f5..6a75ad815df 100644 --- a/doc/governance/gov_api_schemas/classic.rst +++ b/doc/governance/gov_api_schemas/classic.rst @@ -1,5 +1,5 @@ -Classic API -=========== +Classic API (Deprecated) +======================== Available in CCF versions before 5.0.0. diff --git a/doc/governance/hsm_keys.rst b/doc/governance/hsm_keys.rst index 6360e0da81d..ce305f377a3 100644 --- a/doc/governance/hsm_keys.rst +++ b/doc/governance/hsm_keys.rst @@ -121,7 +121,7 @@ Like ``ccf_cose_sign1``, the output can be sent directly to the service via curl --content proposal.json \ --signing-cert $IDENTITY_CERT_NAME.pem \ --signature signature \ - | curl https:///gov/members/proposals:create?api-version=2023-06-01-preview \ + | curl https:///gov/members/proposals:create?api-version=2024-07-01 \ --cacert service_cert.pem \ --data-binary @- \ -H "content-type: application/cose" diff --git a/doc/governance/member_rpc_api.rst b/doc/governance/member_rpc_api.rst index 8da0754bd82..4826e71dd5f 100644 --- a/doc/governance/member_rpc_api.rst +++ b/doc/governance/member_rpc_api.rst @@ -7,6 +7,7 @@ Multiple API versions are available, with the versions supported by the current .. toctree:: + gov_api_schemas/2024-07-01 gov_api_schemas/2023-06-01-preview gov_api_schemas/classic gov_api_schemas/upgrading_from_classic diff --git a/doc/governance/open_network.rst b/doc/governance/open_network.rst index 017e5aa1cee..d75e6ad9f36 100644 --- a/doc/governance/open_network.rst +++ b/doc/governance/open_network.rst @@ -35,7 +35,7 @@ Then, the certificates of trusted users should be registered in CCF via the memb --signing-key member0_privk.pem \ --signing-cert member0_cert.pem \ --content set_user.json \ - | curl https:///gov/members/proposals:create?api-version=2023-06-01-preview \ + | curl https:///gov/members/proposals:create?api-version=2024-07-01 \ --cacert service_cert.pem \ --data-binary @- \ -H "content-type: application/cose" @@ -64,7 +64,7 @@ Other members are then allowed to vote for the proposal, using the proposal id r --signing-key member0_privk.pem \ --signing-cert member0_cert.pem \ --content vote_accept.json \ - | curl https:///gov/members/proposals/f665047e3d1eb184a7b7921944a8ab543cfff117aab5b6358dc87f9e70278253/ballots/2af6cb6c0af07818186f7ef7151061174c3cb74b4a4c30a04a434f0c2b00a8c0:submit?api-version=2023-06-01-preview \ + | curl https:///gov/members/proposals/f665047e3d1eb184a7b7921944a8ab543cfff117aab5b6358dc87f9e70278253/ballots/2af6cb6c0af07818186f7ef7151061174c3cb74b4a4c30a04a434f0c2b00a8c0:submit?api-version=2024-07-01 \ --cacert service_cert.pem \ --data-binary @- \ -H "content-type: application/cose" @@ -84,7 +84,7 @@ Other members are then allowed to vote for the proposal, using the proposal id r --signing-key member1_privk.pem \ --signing-cert member1_cert.pem \ --content vote_accept.json \ - | curl https:///gov/members/proposals/f665047e3d1eb184a7b7921944a8ab543cfff117aab5b6358dc87f9e70278253/ballots/75b86775f1253c308f4e9aeddf912d40b8d77db9eaa9a0f0026f581920d5e9b8:submit?api-version=2023-06-01-preview \ + | curl https:///gov/members/proposals/f665047e3d1eb184a7b7921944a8ab543cfff117aab5b6358dc87f9e70278253/ballots/75b86775f1253c308f4e9aeddf912d40b8d77db9eaa9a0f0026f581920d5e9b8:submit?api-version=2024-07-01 \ --cacert service_cert.pem \ --data-binary @- \ -H "content-type: application/cose" @@ -177,7 +177,7 @@ Once users are added to the opening network, members should create a proposal to --signing-key member0_privk.pem \ --signing-cert member0_cert.pem \ --content transition_service_to_open.json - | curl https:///gov/members/proposals:create?api-version=2023-06-01-preview \ + | curl https:///gov/members/proposals:create?api-version=2024-07-01 \ --cacert service_cert.pem \ --data-binary @- \ -H "content-type: application/cose" diff --git a/doc/governance/proposals.rst b/doc/governance/proposals.rst index b38c9a55938..67ac9aab68d 100644 --- a/doc/governance/proposals.rst +++ b/doc/governance/proposals.rst @@ -280,7 +280,7 @@ For example, ``member1`` may submit a proposal to add a new member (``member4``) --signing-key member1_privk.pem \ --signing-cert member1_cert.pem \ --content add_member.json \ - | curl https:///gov/members/proposals:create?api-version=2023-06-01-preview \ + | curl https:///gov/members/proposals:create?api-version=2024-07-01 \ --cacert service_cert.pem \ --data-binary @- \ -H "content-type: application/cose" @@ -315,7 +315,7 @@ Here a new proposal has successfully been created, and nobody has yet voted for --signing-key member1_privk.pem \ --signing-cert member1_cert.pem \ --content vote_accept.json \ - | curl https:///gov/members/proposals/d4ec2de82267f97d3d1b464020af0bd3241f1bedf769f0fee73cd00f08e9c7fd/ballots/52af2620fa1b005a93d55d7d819a249ee2cb79f5262f54e8db794c5281a0ce73:submit?api-version=2023-06-01-preview \ + | curl https:///gov/members/proposals/d4ec2de82267f97d3d1b464020af0bd3241f1bedf769f0fee73cd00f08e9c7fd/ballots/52af2620fa1b005a93d55d7d819a249ee2cb79f5262f54e8db794c5281a0ce73:submit?api-version=2024-07-01 \ --cacert service_cert.pem \ --data-binary @- \ -H "content-type: application/cose" @@ -334,7 +334,7 @@ Here a new proposal has successfully been created, and nobody has yet voted for --signing-key member2_privk.pem \ --signing-cert member2_cert.pem \ --content vote_reject.json \ - | curl https:///gov/members/proposals/d4ec2de82267f97d3d1b464020af0bd3241f1bedf769f0fee73cd00f08e9c7fd/ballots/fe6ed012e8184f28afb48d0d58dca7f461dc997c43179acf97362dc0b76ddeb7:submit?api-version=2023-06-01-preview \ + | curl https:///gov/members/proposals/d4ec2de82267f97d3d1b464020af0bd3241f1bedf769f0fee73cd00f08e9c7fd/ballots/fe6ed012e8184f28afb48d0d58dca7f461dc997c43179acf97362dc0b76ddeb7:submit?api-version=2024-07-01 \ --cacert service_cert.pem \ --data-binary @- \ -H "content-type: application/cose" @@ -353,7 +353,7 @@ Here a new proposal has successfully been created, and nobody has yet voted for --signing-key member3_privk.pem \ --signing-cert member3_cert.pem \ --content vote_accept.json \ - | curl https:///gov/members/proposals/d4ec2de82267f97d3d1b464020af0bd3241f1bedf769f0fee73cd00f08e9c7fd/ballots/75b86775f1253c308f4e9aeddf912d40b8d77db9eaa9a0f0026f581920d5e9b8:submit?api-version=2023-06-01-preview \ + | curl https:///gov/members/proposals/d4ec2de82267f97d3d1b464020af0bd3241f1bedf769f0fee73cd00f08e9c7fd/ballots/75b86775f1253c308f4e9aeddf912d40b8d77db9eaa9a0f0026f581920d5e9b8:submit?api-version=2024-07-01 \ --cacert service_cert.pem \ --data-binary @- \ -H "content-type: application/cose" @@ -377,7 +377,7 @@ The details of pending proposals, can be queried from the service by calling :ht .. code-block:: bash - $ curl https:///gov/members/proposals/d4ec2de82267f97d3d1b464020af0bd3241f1bedf769f0fee73cd00f08e9c7fd?api-version=2023-06-01-preview --cacert service_cert.pem -X GET + $ curl https:///gov/members/proposals/d4ec2de82267f97d3d1b464020af0bd3241f1bedf769f0fee73cd00f08e9c7fd?api-version=2024-07-01 --cacert service_cert.pem -X GET { "ballotCount": 3, "finalVotes": { @@ -403,7 +403,7 @@ At any stage during the voting process, before the proposal is accepted, the pro --ccf-gov-msg-proposal_id d4ec2de82267f97d3d1b464020af0bd3241f1bedf769f0fee73cd00f08e9c7fd \ --signing-key member1_privk.pem \ --signing-cert member1_cert.pem \ - | curl https:///gov/members/proposals/d4ec2de82267f97d3d1b464020af0bd3241f1bedf769f0fee73cd00f08e9c7fd:withdraw?api-version=2023-06-01-preview \ + | curl https:///gov/members/proposals/d4ec2de82267f97d3d1b464020af0bd3241f1bedf769f0fee73cd00f08e9c7fd:withdraw?api-version=2024-07-01 \ --cacert service_cert.pem \ --data-binary @- \ -H "content-type: application/cose" diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/Ballots_Get.json b/doc/schemas/gov/2023-06-01-preview/examples/Ballots_Get.json similarity index 100% rename from doc/schemas/mccf/2023-06-01-preview/examples/Ballots_Get.json rename to doc/schemas/gov/2023-06-01-preview/examples/Ballots_Get.json diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/Ballots_Submit.json b/doc/schemas/gov/2023-06-01-preview/examples/Ballots_Submit.json similarity index 100% rename from doc/schemas/mccf/2023-06-01-preview/examples/Ballots_Submit.json rename to doc/schemas/gov/2023-06-01-preview/examples/Ballots_Submit.json diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/EncryptedShares_Get.json b/doc/schemas/gov/2023-06-01-preview/examples/EncryptedShares_Get.json similarity index 100% rename from doc/schemas/mccf/2023-06-01-preview/examples/EncryptedShares_Get.json rename to doc/schemas/gov/2023-06-01-preview/examples/EncryptedShares_Get.json diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/Proposals_Create.json b/doc/schemas/gov/2023-06-01-preview/examples/Proposals_Create.json similarity index 100% rename from doc/schemas/mccf/2023-06-01-preview/examples/Proposals_Create.json rename to doc/schemas/gov/2023-06-01-preview/examples/Proposals_Create.json diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/Proposals_Get.json b/doc/schemas/gov/2023-06-01-preview/examples/Proposals_Get.json similarity index 100% rename from doc/schemas/mccf/2023-06-01-preview/examples/Proposals_Get.json rename to doc/schemas/gov/2023-06-01-preview/examples/Proposals_Get.json diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/Proposals_GetActions.json b/doc/schemas/gov/2023-06-01-preview/examples/Proposals_GetActions.json similarity index 100% rename from doc/schemas/mccf/2023-06-01-preview/examples/Proposals_GetActions.json rename to doc/schemas/gov/2023-06-01-preview/examples/Proposals_GetActions.json diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/Proposals_List.json b/doc/schemas/gov/2023-06-01-preview/examples/Proposals_List.json similarity index 100% rename from doc/schemas/mccf/2023-06-01-preview/examples/Proposals_List.json rename to doc/schemas/gov/2023-06-01-preview/examples/Proposals_List.json diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/Proposals_Withdraw.json b/doc/schemas/gov/2023-06-01-preview/examples/Proposals_Withdraw.json similarity index 100% rename from doc/schemas/mccf/2023-06-01-preview/examples/Proposals_Withdraw.json rename to doc/schemas/gov/2023-06-01-preview/examples/Proposals_Withdraw.json diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_GetConstitution.json b/doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetConstitution.json similarity index 100% rename from doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_GetConstitution.json rename to doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetConstitution.json diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_GetJoinPolicies.json b/doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetJoinPolicies.json similarity index 99% rename from doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_GetJoinPolicies.json rename to doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetJoinPolicies.json index 2584b9f2b60..386a37d76ca 100644 --- a/doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_GetJoinPolicies.json +++ b/doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetJoinPolicies.json @@ -30,4 +30,4 @@ } } } -} \ No newline at end of file +} diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_GetJsApp.json b/doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetJsApp.json similarity index 100% rename from doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_GetJsApp.json rename to doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetJsApp.json diff --git a/doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetJwkInfo.json b/doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetJwkInfo.json new file mode 100644 index 00000000000..1b602bf9ebb --- /dev/null +++ b/doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetJwkInfo.json @@ -0,0 +1,29 @@ +{ + "title": "ServiceState_GetJwkInfo", + "operationId": "ServiceState_GetJwkInfo", + "parameters": { + "api-version": "2023-06-01-preview" + }, + "responses": { + "200": { + "body": { + "issuers": { + "idprovider.myservice.example.com": { + "keyFilter": "All", + "autoRefresh": true, + "caCertBundleName": "MyIdProviderCa" + } + }, + "caCertBundles": { + "MyIdProviderCa": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n" + }, + "keys": { + "idprovider_kida": { + "certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n", + "issuer": "idprovider.myservice.example.com" + } + } + } + } + } +} diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_GetMember.json b/doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetMember.json similarity index 100% rename from doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_GetMember.json rename to doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetMember.json diff --git a/doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetNode.json b/doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetNode.json new file mode 100644 index 00000000000..8be95c14d70 --- /dev/null +++ b/doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetNode.json @@ -0,0 +1,29 @@ +{ + "title": "ServiceState_GetNode", + "operationId": "ServiceState_GetNode", + "parameters": { + "api-version": "2023-06-01-preview", + "nodeId": "7e87b5de68f7edb26d2c31b69eda2cb3fac6ec125fdaafecdbe184abc5f61573" + }, + "responses": { + "200": { + "body": { + "nodeId": "7e87b5de68f7edb26d2c31b69eda2cb3fac6ec125fdaafecdbe184abc5f61573", + "status": "Trusted", + "certificate": "-----BEGIN CERTIFICATE-----\nMIIByDCCAU6gAwIBAgIQBU64KAw8A7HsEUJCvArBWDAKBggqhkjOPQQDAzATMREw\nDwYDVQQDDAhDQ0YgTm9kZTAeFw0yMzA1MTcxMzUwMzBaFw0yMzA1MTgxMzUwMjla\nMBMxETAPBgNVBAMMCENDRiBOb2RlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEqo97\nwuOBeYkmXGcDXAuGSQfDbTplLGyvls42TcwntLN/GkHxj6pe0l6h7BC0VV828J5/\na21q6sATQsXyFpZxIxIB6R/5s2blslk6INVuq03qkGz8hmGrpI/MJh//89Wjo2cw\nZTASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBR7QYSt32ibJwNKLAbfdeMu\nuyy6uDAfBgNVHSMEGDAWgBR7QYSt32ibJwNKLAbfdeMuuyy6uDAPBgNVHREECDAG\nhwR/yGnoMAoGCCqGSM49BAMDA2gAMGUCMBS9Hhd4mHjPjJ16n1L6KBshAzlT1IAA\n4jiVaTXqc6shnvfoHljw54jCVm/KpKAzRQIxANS8KrmXhW3cr4rkYWHipJEXzMJe\n8ZL6xWgCY6Fb63JNEYpQP+W3HZqaqKJrdvgTyw==\n-----END CERTIFICATE-----\n", + "retiredCommitted": false, + "quoteInfo": { + "format": "OE_SGX_v1", + "quote": "iqCn2D8gcLapGOmaS/wFlg==", + "endorsements": "xIuY7WOg/FR7/tlqDAWcxQ==" + }, + "rpcInterfaces": { + "publicHttps": { + "publishedAddress": "ccf.dev:12345", + "protocol": "HTTP1" + } + } + } + } + } +} diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_GetServiceInfo.json b/doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetServiceInfo.json similarity index 100% rename from doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_GetServiceInfo.json rename to doc/schemas/gov/2023-06-01-preview/examples/ServiceState_GetServiceInfo.json diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_ListMembers.json b/doc/schemas/gov/2023-06-01-preview/examples/ServiceState_ListMembers.json similarity index 100% rename from doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_ListMembers.json rename to doc/schemas/gov/2023-06-01-preview/examples/ServiceState_ListMembers.json diff --git a/doc/schemas/gov/2023-06-01-preview/examples/ServiceState_ListNodes.json b/doc/schemas/gov/2023-06-01-preview/examples/ServiceState_ListNodes.json new file mode 100644 index 00000000000..e844e179e60 --- /dev/null +++ b/doc/schemas/gov/2023-06-01-preview/examples/ServiceState_ListNodes.json @@ -0,0 +1,50 @@ +{ + "title": "ServiceState_ListNodes", + "operationId": "ServiceState_ListNodes", + "parameters": { + "api-version": "2023-06-01-preview" + }, + "responses": { + "200": { + "body": { + "value": [ + { + "nodeId": "7e87b5de68f7edb26d2c31b69eda2cb3fac6ec125fdaafecdbe184abc5f61573", + "status": "Trusted", + "certificate": "-----BEGIN CERTIFICATE-----\nMIIByDCCAU6gAwIBAgIQBU64KAw8A7HsEUJCvArBWDAKBggqhkjOPQQDAzATMREw\nDwYDVQQDDAhDQ0YgTm9kZTAeFw0yMzA1MTcxMzUwMzBaFw0yMzA1MTgxMzUwMjla\nMBMxETAPBgNVBAMMCENDRiBOb2RlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEqo97\nwuOBeYkmXGcDXAuGSQfDbTplLGyvls42TcwntLN/GkHxj6pe0l6h7BC0VV828J5/\na21q6sATQsXyFpZxIxIB6R/5s2blslk6INVuq03qkGz8hmGrpI/MJh//89Wjo2cw\nZTASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBR7QYSt32ibJwNKLAbfdeMu\nuyy6uDAfBgNVHSMEGDAWgBR7QYSt32ibJwNKLAbfdeMuuyy6uDAPBgNVHREECDAG\nhwR/yGnoMAoGCCqGSM49BAMDA2gAMGUCMBS9Hhd4mHjPjJ16n1L6KBshAzlT1IAA\n4jiVaTXqc6shnvfoHljw54jCVm/KpKAzRQIxANS8KrmXhW3cr4rkYWHipJEXzMJe\n8ZL6xWgCY6Fb63JNEYpQP+W3HZqaqKJrdvgTyw==\n-----END CERTIFICATE-----\n", + "retiredCommitted": false, + "quoteInfo": { + "format": "OE_SGX_v1", + "quote": "iqCn2D8gcLapGOmaS/wFlg==", + "endorsements": "xIuY7WOg/FR7/tlqDAWcxQ==" + }, + "rpcInterfaces": { + "publicHttps": { + "publishedAddress": "ccf.dev:12345", + "protocol": "HTTP1" + } + } + }, + { + "nodeId": "5bc78bd280bbd86387bbc448b5b7defbc2ecded715537b3aa742ceae35ab4302", + "status": "Retired", + "certificate": "-----BEGIN CERTIFICATE-----\nMIIByDCCAU6gAwIBAgIQOBe5SrcwReWmSzTjzj2HDjAKBggqhkjOPQQDAzATMREw\nDwYDVQQDDAhDQ0YgTm9kZTAeFw0yMzA1MTcxMzUwMzFaFw0yMzA1MTgxMzUwMzBa\nMBMxETAPBgNVBAMMCENDRiBOb2RlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE74qL\nAc/45tiriN5MuquYhHVdMGQRvYSm08HBfYcODtET88qC0A39o6Y2TmfbIn6BdjMG\nkD58o377ZMTaApQu/oJcwt7qZ9/LE8j8WU2qHn0cPTlpwH/2tiud2w+U3voSo2cw\nZTASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBS9FJNwWSXtUpHaBV57EwTW\noM8vHjAfBgNVHSMEGDAWgBS9FJNwWSXtUpHaBV57EwTWoM8vHjAPBgNVHREECDAG\nhwR/xF96MAoGCCqGSM49BAMDA2gAMGUCMQDKxpjPToJ7VSqKqQSeMuW9tr4iL+9I\n7gTGdGwiIYV1qTSS35Sk9XQZ0VpSa58c/5UCMEgmH71k7XlTGVUypm4jAgjpC46H\ns+hJpGMvyD9dKzEpZgmZYtghbyakUkwBiqmFQA==\n-----END CERTIFICATE-----\n", + "retiredCommitted": true, + "quoteInfo": { + "format": "OE_SGX_v1", + "quote": "4n3t9RVQZomjwsAZyiyAuQ==", + "endorsements": "lvpmei0YwtfvVa4RaK8n+g==" + }, + "rpcInterfaces": { + "publicHttps": { + "publishedAddress": "ccf.dev:12345", + "protocol": "HTTP1" + } + } + } + ], + "nextLink": "https://microsoft.com/a" + } + } + } +} diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/Shares_Submit.json b/doc/schemas/gov/2023-06-01-preview/examples/Shares_Submit.json similarity index 100% rename from doc/schemas/mccf/2023-06-01-preview/examples/Shares_Submit.json rename to doc/schemas/gov/2023-06-01-preview/examples/Shares_Submit.json diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/StateDigests_Acknowledge.json b/doc/schemas/gov/2023-06-01-preview/examples/StateDigests_Acknowledge.json similarity index 100% rename from doc/schemas/mccf/2023-06-01-preview/examples/StateDigests_Acknowledge.json rename to doc/schemas/gov/2023-06-01-preview/examples/StateDigests_Acknowledge.json diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/StateDigests_Get.json b/doc/schemas/gov/2023-06-01-preview/examples/StateDigests_Get.json similarity index 100% rename from doc/schemas/mccf/2023-06-01-preview/examples/StateDigests_Get.json rename to doc/schemas/gov/2023-06-01-preview/examples/StateDigests_Get.json diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/StateDigests_Update.json b/doc/schemas/gov/2023-06-01-preview/examples/StateDigests_Update.json similarity index 99% rename from doc/schemas/mccf/2023-06-01-preview/examples/StateDigests_Update.json rename to doc/schemas/gov/2023-06-01-preview/examples/StateDigests_Update.json index 51637181b29..cf959313b16 100644 --- a/doc/schemas/mccf/2023-06-01-preview/examples/StateDigests_Update.json +++ b/doc/schemas/gov/2023-06-01-preview/examples/StateDigests_Update.json @@ -14,4 +14,4 @@ } } } -} \ No newline at end of file +} diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/Transactions_Get.json b/doc/schemas/gov/2023-06-01-preview/examples/Transactions_Get.json similarity index 100% rename from doc/schemas/mccf/2023-06-01-preview/examples/Transactions_Get.json rename to doc/schemas/gov/2023-06-01-preview/examples/Transactions_Get.json diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/Transactions_GetCommit.json b/doc/schemas/gov/2023-06-01-preview/examples/Transactions_GetCommit.json similarity index 100% rename from doc/schemas/mccf/2023-06-01-preview/examples/Transactions_GetCommit.json rename to doc/schemas/gov/2023-06-01-preview/examples/Transactions_GetCommit.json diff --git a/doc/schemas/mccf/2023-06-01-preview/mccfgov.json b/doc/schemas/gov/2023-06-01-preview/gov.json similarity index 97% rename from doc/schemas/mccf/2023-06-01-preview/mccfgov.json rename to doc/schemas/gov/2023-06-01-preview/gov.json index cafabab8cd9..02021832430 100644 --- a/doc/schemas/mccf/2023-06-01-preview/mccfgov.json +++ b/doc/schemas/gov/2023-06-01-preview/gov.json @@ -1164,14 +1164,22 @@ "type": "object", "description": "A compact summary of the service's state up to a certain point in time, updated and signed by members to indicate their participation in and approval of the service.", "properties": { - "digest": { + "memberId": { + "$ref": "#/definitions/memberId", + "description": "Identifier for member this stateDigest applies to.", + "x-ms-mutability": [ + "read" + ] + }, + "stateDigest": { "type": "string", "description": "Hex-encoding of SHA-256 hash of the root of the service's merkle tree. This should be signed by a new member and submitted as an ACK to mark that member as Active.", "pattern": "^[a-f0-9]{64}$" } }, "required": [ - "digest" + "memberId", + "stateDigest" ] }, "Azure.Core.Foundations.Error": { @@ -1534,6 +1542,19 @@ "constitution" ] }, + "ServiceState.FeedInfo": { + "type": "object", + "description": "Collection of claims regarding a specific feed.", + "properties": { + "svn": { + "type": "string", + "description": "Security version number claimed by this endorser." + } + }, + "required": [ + "svn" + ] + }, "ServiceState.ForwardingRequired": { "type": "string", "description": "Describes the forwarding behavior of a specific endpoint. Write requests cannot be executed on a backup, so will generally be forwarded by any backup node which receives them to the current primary. Future requests on the same session may then be forwarded to maintain session consistency.", @@ -1694,6 +1715,23 @@ "$ref": "#/definitions/ServiceState.JsEndpointInfo" } }, + "ServiceState.Jwk": { + "type": "object", + "description": "Describes a single JWK.", + "properties": { + "certificate": { + "$ref": "#/definitions/ServiceState.pem", + "description": "x509 cert used to validate claims made by this key." + }, + "issuer": { + "type": "string", + "description": "Issuer ID of entity who issued this key." + } + }, + "required": [ + "certificate" + ] + }, "ServiceState.JwkInfo": { "type": "object", "description": "Describes what Javascript Web Tokens (JWTs) are accepted by the service, and how they will be validated.", @@ -1711,11 +1749,19 @@ "additionalProperties": { "$ref": "#/definitions/ServiceState.caCertBundle" } + }, + "keys": { + "type": "object", + "description": "Collection of retrieved JWKs. Keyed by kid.", + "additionalProperties": { + "$ref": "#/definitions/ServiceState.Jwk" + } } }, "required": [ "issuers", - "caCertBundles" + "caCertBundles", + "keys" ] }, "ServiceState.JwtIssuer": { @@ -1789,6 +1835,10 @@ "certificate": { "$ref": "#/definitions/ServiceState.pem", "description": "x509 certificate used as this member's identity." + }, + "publicEncryptionKey": { + "$ref": "#/definitions/ServiceState.pem", + "description": "x509 key used to encrypt this member's key shares, if they are a recovery member." } }, "required": [ @@ -1948,7 +1998,7 @@ "description": "Transaction ID at which this service was first created. If this is a recovery of a previous service, this will indicate when the current service was recovered." }, "previousServiceCreationTransactionId": { - "$ref": "#/definitions/ServiceState.pem", + "$ref": "#/definitions/transactionId", "description": "Transaction ID at which the predecessor service was created, if this service is a recovery. If this is an original service rather than a recovery, this will be omitted." }, "serviceData": { @@ -2063,10 +2113,9 @@ }, "uvmEndorsements": { "type": "object", - "description": "Collection of acceptable UVM endorsements.", + "description": "Collection of acceptable UVM endorsements. Keyed by endorser's did.", "additionalProperties": { - "format": "byte", - "type": "string" + "$ref": "#/definitions/ServiceState.UvmEndorsementFeeds" } } }, @@ -2102,6 +2151,13 @@ ], "x-ms-discriminator-value": "AMD_SEV_SNP_v1" }, + "ServiceState.UvmEndorsementFeeds": { + "type": "object", + "description": "Collection of endorsement feeds, keyed by feed name.", + "additionalProperties": { + "$ref": "#/definitions/ServiceState.FeedInfo" + } + }, "ServiceState.caCertBundle": { "type": "string", "description": "Chain of endorsed certificates (PEM format) leading to a CA." diff --git a/doc/schemas/gov/2024-07-01/examples/Ballots_Get.json b/doc/schemas/gov/2024-07-01/examples/Ballots_Get.json new file mode 100644 index 00000000000..d14410a1147 --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/Ballots_Get.json @@ -0,0 +1,16 @@ +{ + "title": "Ballots_Get", + "operationId": "Ballots_Get", + "parameters": { + "api-version": "2024-07-01", + "proposalId": "1c04c5bb4bdc207dbf35bc4b32dbf92cbc23eabb34a6e8b163b2de2c7833e87b", + "memberId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970" + }, + "responses": { + "200": { + "body": { + "script": "export function vote (rawProposal, proposerId) { return true }" + } + } + } +} diff --git a/doc/schemas/gov/2024-07-01/examples/Ballots_Submit.json b/doc/schemas/gov/2024-07-01/examples/Ballots_Submit.json new file mode 100644 index 00000000000..282d9d686db --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/Ballots_Submit.json @@ -0,0 +1,24 @@ +{ + "title": "Ballots_Submit", + "operationId": "Ballots_Submit", + "parameters": { + "api-version": "2024-07-01", + "proposalId": "1c04c5bb4bdc207dbf35bc4b32dbf92cbc23eabb34a6e8b163b2de2c7833e87b", + "memberId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970", + "body": "{binary COSE Sign1}" + }, + "responses": { + "200": { + "body": { + "proposalId": "1c04c5bb4bdc207dbf35bc4b32dbf92cbc23eabb34a6e8b163b2de2c7833e87b", + "proposerId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970", + "proposalState": "Open", + "ballotCount": 2, + "finalVotes": { + "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970": true, + "b9626e3856b3ef3b433e612d59fbb9edd71cfa2efc772bcfbb50aaa9b6e033f7": false + } + } + } + } +} diff --git a/doc/schemas/gov/2024-07-01/examples/EncryptedShares_Get.json b/doc/schemas/gov/2024-07-01/examples/EncryptedShares_Get.json new file mode 100644 index 00000000000..6728ede91f0 --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/EncryptedShares_Get.json @@ -0,0 +1,15 @@ +{ + "title": "EncryptedShares_Get", + "operationId": "EncryptedShares_Get", + "parameters": { + "api-version": "2024-07-01", + "memberId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970" + }, + "responses": { + "200": { + "body": { + "encryptedShare": "ZW5jcnlwdGVkU2hhcmUx" + } + } + } +} diff --git a/doc/schemas/gov/2024-07-01/examples/Proposals_Create.json b/doc/schemas/gov/2024-07-01/examples/Proposals_Create.json new file mode 100644 index 00000000000..33e9a87a767 --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/Proposals_Create.json @@ -0,0 +1,19 @@ +{ + "title": "Proposals_Create", + "operationId": "Proposals_Create", + "parameters": { + "api-version": "2024-07-01", + "body": "{binary COSE Sign1}" + }, + "responses": { + "200": { + "body": { + "proposalId": "1c04c5bb4bdc207dbf35bc4b32dbf92cbc23eabb34a6e8b163b2de2c7833e87b", + "proposerId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970", + "proposalState": "Open", + "ballotCount": 0, + "finalVotes": {} + } + } + } +} diff --git a/doc/schemas/gov/2024-07-01/examples/Proposals_Get.json b/doc/schemas/gov/2024-07-01/examples/Proposals_Get.json new file mode 100644 index 00000000000..dbf7e161596 --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/Proposals_Get.json @@ -0,0 +1,22 @@ +{ + "title": "Proposals_Get", + "operationId": "Proposals_Get", + "parameters": { + "api-version": "2024-07-01", + "proposalId": "1c04c5bb4bdc207dbf35bc4b32dbf92cbc23eabb34a6e8b163b2de2c7833e87b" + }, + "responses": { + "200": { + "body": { + "proposalId": "1c04c5bb4bdc207dbf35bc4b32dbf92cbc23eabb34a6e8b163b2de2c7833e87b", + "proposerId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970", + "proposalState": "Open", + "ballotCount": 2, + "finalVotes": { + "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970": true, + "b9626e3856b3ef3b433e612d59fbb9edd71cfa2efc772bcfbb50aaa9b6e033f7": false + } + } + } + } +} diff --git a/doc/schemas/gov/2024-07-01/examples/Proposals_GetActions.json b/doc/schemas/gov/2024-07-01/examples/Proposals_GetActions.json new file mode 100644 index 00000000000..7637c07885e --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/Proposals_GetActions.json @@ -0,0 +1,23 @@ +{ + "title": "Proposals_GetActions", + "operationId": "Proposals_GetActions", + "parameters": { + "api-version": "2024-07-01", + "proposalId": "1c04c5bb4bdc207dbf35bc4b32dbf92cbc23eabb34a6e8b163b2de2c7833e87b" + }, + "responses": { + "200": { + "body": { + "actions": [ + { + "name": "set_member", + "args": { + "cert": "-----BEGIN CERTIFICATE-----\nMIIBtzCCATygAwIBAgIUYqXLFcT1aCENVpgp2K+Vv53cauEwCgYIKoZIzj0EAwMw\nEjEQMA4GA1UEAwwHbWVtYmVyMzAeFw0yMzA1MTcxMzUwMzJaFw0yNDA1MTYxMzUw\nMzJaMBIxEDAOBgNVBAMMB21lbWJlcjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQI\ngWV8Lcf+eegGXVj1I4N8jWcfTb6MRt0Znl8aFOBBwZ5lgRlTePYLHBb81wOJaX+k\nIYqHRaI3Wblg72gV/dhf4qBYw9ENqJtE2ClenYkRFAX2/1GwjxTOf9XGpBUt5Rij\nUzBRMB0GA1UdDgQWBBT7oAebRrqSDSG89jW0nFF5fHRRTzAfBgNVHSMEGDAWgBT7\noAebRrqSDSG89jW0nFF5fHRRTzAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMD\nA2kAMGYCMQCmCKWLEbCooecDiuMyUf/B2vppNZ75U96B2ypg88Xy5y4xhRV1qoCT\nRT4sUCFl6ioCMQCKm0df2DzlRbhX6+0i6KikBkUf9kFowb5ctikJsym0rTigpPZC\nHaZlaQD2pNBud/0=\n-----END CERTIFICATE-----\n", + "encryption_pub_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzIh4oWoiTFCu/8tsfmo9\njTDryaTrL7wo8+HJAGUTL827CiZ8Rm9wgo7iJDOza7UPaPnXpR6kIlZbdItDOx9k\nmJSVWbDMufaqqs+y/i+WrTiDqL02zbT/lI4kx5l7Wyu0VEHT5GmSKQiVyJt/Q4vE\n1b9rKNy3Ol1g5VuW9PKOHFz3tvjWksVWXi16qulN3IjAhSFVRtasbqdNSNdDbirv\nLTe24Y9v7UP8CI3qgjr3x8qLYM/X0ou4ZcJvXWVtxZfQLGVgyZcgHD6OtbYJr9Iy\neh/x+G3pPFg2eQY8xNZgqqtH1StKcI++eD7iSDosKRkN3efCKLeKStg6F/xluarc\nkQIDAQAB\n-----END PUBLIC KEY-----\n" + } + } + ] + } + } + } +} diff --git a/doc/schemas/gov/2024-07-01/examples/Proposals_List.json b/doc/schemas/gov/2024-07-01/examples/Proposals_List.json new file mode 100644 index 00000000000..13dc5511214 --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/Proposals_List.json @@ -0,0 +1,26 @@ +{ + "title": "Proposals_List", + "operationId": "Proposals_List", + "parameters": { + "api-version": "2024-07-01" + }, + "responses": { + "200": { + "body": { + "value": [ + { + "proposalId": "1c04c5bb4bdc207dbf35bc4b32dbf92cbc23eabb34a6e8b163b2de2c7833e87b", + "proposerId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970", + "proposalState": "Open", + "ballotCount": 2, + "finalVotes": { + "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970": true, + "b9626e3856b3ef3b433e612d59fbb9edd71cfa2efc772bcfbb50aaa9b6e033f7": false + } + } + ], + "nextLink": "https://microsoft.com/avwpnzmy" + } + } + } +} diff --git a/doc/schemas/gov/2024-07-01/examples/Proposals_Withdraw.json b/doc/schemas/gov/2024-07-01/examples/Proposals_Withdraw.json new file mode 100644 index 00000000000..e6133c71e8e --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/Proposals_Withdraw.json @@ -0,0 +1,23 @@ +{ + "title": "Proposals_Withdraw", + "operationId": "Proposals_Withdraw", + "parameters": { + "api-version": "2024-07-01", + "proposalId": "1c04c5bb4bdc207dbf35bc4b32dbf92cbc23eabb34a6e8b163b2de2c7833e87b", + "body": "{binary COSE Sign1}" + }, + "responses": { + "200": { + "body": { + "proposalId": "1c04c5bb4bdc207dbf35bc4b32dbf92cbc23eabb34a6e8b163b2de2c7833e87b", + "proposerId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970", + "proposalState": "Withdrawn", + "ballotCount": 2, + "finalVotes": { + "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970": true, + "b9626e3856b3ef3b433e612d59fbb9edd71cfa2efc772bcfbb50aaa9b6e033f7": false + } + } + } + } +} diff --git a/doc/schemas/gov/2024-07-01/examples/ServiceState_GetConstitution.json b/doc/schemas/gov/2024-07-01/examples/ServiceState_GetConstitution.json new file mode 100644 index 00000000000..4d0cc694baa --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/ServiceState_GetConstitution.json @@ -0,0 +1,14 @@ +{ + "title": "ServiceState_GetConstitution", + "operationId": "ServiceState_GetConstitution", + "parameters": { + "api-version": "2024-07-01" + }, + "responses": { + "200": { + "body": { + "constitution": "export function validate(input) {\n ...\n}\n\nexport function resolve(proposal, proposerId, votes) {\n ...\n}\n\nexport function apply(proposal, proposalId) {\n ...\n}\n" + } + } + } +} diff --git a/doc/schemas/gov/2024-07-01/examples/ServiceState_GetJoinPolicies.json b/doc/schemas/gov/2024-07-01/examples/ServiceState_GetJoinPolicies.json new file mode 100644 index 00000000000..354c8ddc12c --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/ServiceState_GetJoinPolicies.json @@ -0,0 +1,33 @@ +{ + "title": "ServiceState_GetJoinPolicies", + "operationId": "ServiceState_GetJoinPolicies", + "parameters": { + "api-version": "2024-07-01" + }, + "responses": { + "200": { + "body": { + "sgx": { + "measurements": [ + "cs/RoNCp2UCxpN+i1UnVYw==" + ] + }, + "snp": { + "measurements": [ + "XqJZLOA9/xCx9nnsDch4vw==" + ], + "hostData": { + "key9497": "NiNrjmA9/aSj4F076mVdrA==" + }, + "uvmEndorsements": { + "did:x509:0:sha256:I__iuL25oXEVFdTP_aBLx_eT1RPHbCQ_ECBQfYZpt9s::eku:1.3.6.1.4.1.311.76.59.1.2": { + "ContainerPlat-AMD-UVM": { + "svn": "100" + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/doc/schemas/gov/2024-07-01/examples/ServiceState_GetJsApp.json b/doc/schemas/gov/2024-07-01/examples/ServiceState_GetJsApp.json new file mode 100644 index 00000000000..4866276a1bd --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/ServiceState_GetJsApp.json @@ -0,0 +1,27 @@ +{ + "title": "ServiceState_GetJsApp", + "operationId": "ServiceState_GetJsApp", + "parameters": { + "api-version": "2024-07-01" + }, + "responses": { + "200": { + "body": { + "endpoints": { + "/compute": { + "post": { + "jsModule": "math.js", + "jsFunction": "compute", + "forwardingRequired": "Sometimes", + "authnPolicies": [ + "user_cert" + ], + "mode": "ReadOnly", + "openApi": {} + } + } + } + } + } + } +} diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_GetJwkInfo.json b/doc/schemas/gov/2024-07-01/examples/ServiceState_GetJwkInfo.json similarity index 92% rename from doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_GetJwkInfo.json rename to doc/schemas/gov/2024-07-01/examples/ServiceState_GetJwkInfo.json index 86aa125d939..412834500d6 100644 --- a/doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_GetJwkInfo.json +++ b/doc/schemas/gov/2024-07-01/examples/ServiceState_GetJwkInfo.json @@ -2,7 +2,7 @@ "title": "ServiceState_GetJwkInfo", "operationId": "ServiceState_GetJwkInfo", "parameters": { - "api-version": "2023-06-01-preview" + "api-version": "2024-07-01" }, "responses": { "200": { diff --git a/doc/schemas/gov/2024-07-01/examples/ServiceState_GetMember.json b/doc/schemas/gov/2024-07-01/examples/ServiceState_GetMember.json new file mode 100644 index 00000000000..d1a1890d411 --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/ServiceState_GetMember.json @@ -0,0 +1,17 @@ +{ + "title": "ServiceState_GetMember", + "operationId": "ServiceState_GetMember", + "parameters": { + "api-version": "2024-07-01", + "memberId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970" + }, + "responses": { + "200": { + "body": { + "memberId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970", + "status": "Accepted", + "certificate": "-----BEGIN CERTIFICATE-----\nMIIBtjCCATygAwIBAgIUQReVbbmYi3jwIKLajvRSSazrlHgwCgYIKoZIzj0EAwMw\nEjEQMA4GA1UEAwwHbWVtYmVyMDAeFw0yMzA1MTcxMzUwMzBaFw0yNDA1MTYxMzUw\nMzBaMBIxEDAOBgNVBAMMB21lbWJlcjAwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQL\nHTNizYCCd+qvH5hMkikWRRb9s3cmD1PIkeoqRIqJ98FF2PgW/cPhM8wyJ3KK8tqS\n7MI6rW8AFgRf2CV3nJ3uNwVrbdgbmmGef8WTyFBXX3VvypntT+jCHDg9HURROAmj\nUzBRMB0GA1UdDgQWBBSljyQ0GfGDm8ODrpcWy364SPRUHjAfBgNVHSMEGDAWgBSl\njyQ0GfGDm8ODrpcWy364SPRUHjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMD\nA2gAMGUCMDUoePU2bJxAt9lXDX0TCQrt1xMBZc5BNvVi2ROEQEKHSetVgzAADzFC\n/8Te+S/+kwIxAJMFEeGSbXaUNxvQLHJehaORV0Bw2FJN+zkb3FAltwlua+REfl/t\nPcn7nq5mpQ0RNQ==\n-----END CERTIFICATE-----\n" + } + } + } +} diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_GetNode.json b/doc/schemas/gov/2024-07-01/examples/ServiceState_GetNode.json similarity index 97% rename from doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_GetNode.json rename to doc/schemas/gov/2024-07-01/examples/ServiceState_GetNode.json index 6dfe08dfb4f..8bdce0670d1 100644 --- a/doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_GetNode.json +++ b/doc/schemas/gov/2024-07-01/examples/ServiceState_GetNode.json @@ -2,7 +2,7 @@ "title": "ServiceState_GetNode", "operationId": "ServiceState_GetNode", "parameters": { - "api-version": "2023-06-01-preview", + "api-version": "2024-07-01", "nodeId": "7e87b5de68f7edb26d2c31b69eda2cb3fac6ec125fdaafecdbe184abc5f61573" }, "responses": { diff --git a/doc/schemas/gov/2024-07-01/examples/ServiceState_GetServiceInfo.json b/doc/schemas/gov/2024-07-01/examples/ServiceState_GetServiceInfo.json new file mode 100644 index 00000000000..05fb2211642 --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/ServiceState_GetServiceInfo.json @@ -0,0 +1,22 @@ +{ + "title": "ServiceState_GetServiceInfo", + "operationId": "ServiceState_GetServiceInfo", + "parameters": { + "api-version": "2024-07-01" + }, + "responses": { + "200": { + "body": { + "status": "Open", + "certificate": "-----BEGIN CERTIFICATE-----\nMIIBvjCCAUSgAwIBAgIRAKMpqEu0tXPD9gmJTV/RDdcwCgYIKoZIzj0EAwMwFjEU\nMBIGA1UEAwwLQ0NGIE5ldHdvcmswHhcNMjMwNTE2MTUxNzIyWhcNMjMwNTE3MTUx\nNzIxWjAWMRQwEgYDVQQDDAtDQ0YgTmV0d29yazB2MBAGByqGSM49AgEGBSuBBAAi\nA2IABKGiSg+X2EofhkL9rmpnvRAsRDMRW1cErnYA7gv3Y1s+g0srVPG5Fh85I2GO\nxVgj/hICXsR/bPPjDW3NLJ7gvzbtU4XnLsixkRPa9mkWM9GePaimUNs6NnbWI/5/\ndZkkSqNWMFQwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUglDhOi9RqGAj\nwT2EFycWlLeZnrIwHwYDVR0jBBgwFoAUglDhOi9RqGAjwT2EFycWlLeZnrIwCgYI\nKoZIzj0EAwMDaAAwZQIwR6PFt+sC1nbFGskq8D+o8dBPihhZGxrthRIUtROYFTWU\ncfw59zRFYGffJH0qXV3tAjEAzldbGZNiFL6sTEmv+lfKdeSfZphZmVQttJ0yQ+l8\nM4qqgkU90BWODS/7RIDFMB73\n-----END CERTIFICATE-----\n", + "recoveryCount": 1, + "creationTransactionId": "7.1672", + "previousServiceCreationTransactionId": "2.1", + "configuration": { + "maximumNodeCertificateValidityDays": 180, + "recentCoseProposalsWindowSize": 100 + } + } + } + } +} diff --git a/doc/schemas/gov/2024-07-01/examples/ServiceState_ListMembers.json b/doc/schemas/gov/2024-07-01/examples/ServiceState_ListMembers.json new file mode 100644 index 00000000000..732e99e2188 --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/ServiceState_ListMembers.json @@ -0,0 +1,31 @@ +{ + "title": "ServiceState_ListMembers", + "operationId": "ServiceState_ListMembers", + "parameters": { + "api-version": "2024-07-01" + }, + "responses": { + "200": { + "body": { + "value": [ + { + "memberId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970", + "status": "Accepted", + "certificate": "-----BEGIN CERTIFICATE-----\nMIIBtjCCATygAwIBAgIUQReVbbmYi3jwIKLajvRSSazrlHgwCgYIKoZIzj0EAwMw\nEjEQMA4GA1UEAwwHbWVtYmVyMDAeFw0yMzA1MTcxMzUwMzBaFw0yNDA1MTYxMzUw\nMzBaMBIxEDAOBgNVBAMMB21lbWJlcjAwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQL\nHTNizYCCd+qvH5hMkikWRRb9s3cmD1PIkeoqRIqJ98FF2PgW/cPhM8wyJ3KK8tqS\n7MI6rW8AFgRf2CV3nJ3uNwVrbdgbmmGef8WTyFBXX3VvypntT+jCHDg9HURROAmj\nUzBRMB0GA1UdDgQWBBSljyQ0GfGDm8ODrpcWy364SPRUHjAfBgNVHSMEGDAWgBSl\njyQ0GfGDm8ODrpcWy364SPRUHjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMD\nA2gAMGUCMDUoePU2bJxAt9lXDX0TCQrt1xMBZc5BNvVi2ROEQEKHSetVgzAADzFC\n/8Te+S/+kwIxAJMFEeGSbXaUNxvQLHJehaORV0Bw2FJN+zkb3FAltwlua+REfl/t\nPcn7nq5mpQ0RNQ==\n-----END CERTIFICATE-----\n" + }, + { + "memberId": "b9626e3856b3ef3b433e612d59fbb9edd71cfa2efc772bcfbb50aaa9b6e033f7", + "status": "Accepted", + "certificate": "-----BEGIN CERTIFICATE-----\nMIIBtTCCATygAwIBAgIUbMeV2BFlZO11PM0FoiuJjmLVSiIwCgYIKoZIzj0EAwMw\nEjEQMA4GA1UEAwwHbWVtYmVyMTAeFw0yMzA1MTcxMzUwMzBaFw0yNDA1MTYxMzUw\nMzBaMBIxEDAOBgNVBAMMB21lbWJlcjEwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAR3\nGPE7tBnEj5MwMMO6y376VQLfPFCVI9+LI4Ndc1ieLRIii+oydrwzthxv10juy+Nl\nSoD67n1y6ehbMB9JKEGMnkBfuZNKuXAqb2h371y2d/jrX/pZmyy3AIICnKYTQ7Oj\nUzBRMB0GA1UdDgQWBBQf2ImVBp4MWgpLz6OlOUY65VGbRTAfBgNVHSMEGDAWgBQf\n2ImVBp4MWgpLz6OlOUY65VGbRTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMD\nA2cAMGQCMDCW/sHEGuxowkv1x1q+/8cRO9YAa3HxASkqz9/MK2r+jyOFawKtaRpc\n7QwvBOkLFwIwEK6Q9aCTrjGkoxITnFmIc+nnv+wh4xRkUNam/nQebMRQSHI9TUXN\n8sQwxjb50U7L\n-----END CERTIFICATE-----\n" + }, + { + "memberId": "ecf07a6c69266e14cedea8cfc0049c04201501f5c7ea5cf7180ad56efbd84714", + "status": "Accepted", + "certificate": "-----BEGIN CERTIFICATE-----\nMIIBtjCCATygAwIBAgIUbpzHWRHXRoDOjyqYlFk7itQ5qWgwCgYIKoZIzj0EAwMw\nEjEQMA4GA1UEAwwHbWVtYmVyMjAeFw0yMzA1MTcxMzUwMzBaFw0yNDA1MTYxMzUw\nMzBaMBIxEDAOBgNVBAMMB21lbWJlcjIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASA\n4495qU2huzUZHWCf/ovT+C28AlDIaGejvc9qxaRKJ+dXAdZ10C6Z3TMXYGKlpE2K\nCz/VyOMsdwBiN8rJs4L1bLWRh3vZnyoVyp3quq34wc90UINv3lNK8XnxcONtkaGj\nUzBRMB0GA1UdDgQWBBQeZ+IKLpQ4nd3CSxxaj+8X+eV+TTAfBgNVHSMEGDAWgBQe\nZ+IKLpQ4nd3CSxxaj+8X+eV+TTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMD\nA2gAMGUCMGWloVqJ7mvY7bFp5vfSPICnpMUL6sat62Ag/2ZZ1FRqWTXokuqRH2UI\nOJyLpI245QIxAKXY58sTZIVzlXkYGp0z3TrTkVQ/pipWD7MpNzr1+7afQWj1Dw+r\npznvF6OHoz0fTA==\n-----END CERTIFICATE-----\n" + } + ], + "nextLink": "https://microsoft.com/ak" + } + } + } +} diff --git a/doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_ListNodes.json b/doc/schemas/gov/2024-07-01/examples/ServiceState_ListNodes.json similarity index 98% rename from doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_ListNodes.json rename to doc/schemas/gov/2024-07-01/examples/ServiceState_ListNodes.json index c5c92917e5c..a53bded08ca 100644 --- a/doc/schemas/mccf/2023-06-01-preview/examples/ServiceState_ListNodes.json +++ b/doc/schemas/gov/2024-07-01/examples/ServiceState_ListNodes.json @@ -2,7 +2,7 @@ "title": "ServiceState_ListNodes", "operationId": "ServiceState_ListNodes", "parameters": { - "api-version": "2023-06-01-preview" + "api-version": "2024-07-01" }, "responses": { "200": { diff --git a/doc/schemas/gov/2024-07-01/examples/Shares_Submit.json b/doc/schemas/gov/2024-07-01/examples/Shares_Submit.json new file mode 100644 index 00000000000..c92a58758ac --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/Shares_Submit.json @@ -0,0 +1,18 @@ +{ + "title": "Shares_Submit", + "operationId": "Shares_Submit", + "parameters": { + "api-version": "2024-07-01", + "memberId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970", + "body": "{binary COSE Sign1}" + }, + "responses": { + "200": { + "body": { + "message": "3/3 recovery shares successfully submitted.", + "submittedCount": 0, + "recoveryThreshold": 0 + } + } + } +} diff --git a/doc/schemas/gov/2024-07-01/examples/StateDigests_Acknowledge.json b/doc/schemas/gov/2024-07-01/examples/StateDigests_Acknowledge.json new file mode 100644 index 00000000000..1aedea69bcf --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/StateDigests_Acknowledge.json @@ -0,0 +1,12 @@ +{ + "title": "StateDigests_Acknowledge", + "operationId": "StateDigests_Acknowledge", + "parameters": { + "api-version": "2024-07-01", + "memberId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970", + "body": "{binary COSE Sign1}" + }, + "responses": { + "204": {} + } +} diff --git a/doc/schemas/gov/2024-07-01/examples/StateDigests_Get.json b/doc/schemas/gov/2024-07-01/examples/StateDigests_Get.json new file mode 100644 index 00000000000..e2839b4b6a9 --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/StateDigests_Get.json @@ -0,0 +1,16 @@ +{ + "title": "StateDigests_Get", + "operationId": "StateDigests_Get", + "parameters": { + "api-version": "2024-07-01", + "memberId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970" + }, + "responses": { + "200": { + "body": { + "memberId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970", + "stateDigest": "1cdc59855bb6b7edee42769ca3767bc9684b7a62ffcfcb8751a75dbe71c28e49" + } + } + } +} diff --git a/doc/schemas/gov/2024-07-01/examples/StateDigests_Update.json b/doc/schemas/gov/2024-07-01/examples/StateDigests_Update.json new file mode 100644 index 00000000000..8af3dda8465 --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/StateDigests_Update.json @@ -0,0 +1,17 @@ +{ + "title": "StateDigests_Update", + "operationId": "StateDigests_Update", + "parameters": { + "api-version": "2024-07-01", + "memberId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970", + "body": "{binary COSE Sign1}" + }, + "responses": { + "200": { + "body": { + "memberId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970", + "stateDigest": "1cdc59855bb6b7edee42769ca3767bc9684b7a62ffcfcb8751a75dbe71c28e49" + } + } + } +} \ No newline at end of file diff --git a/doc/schemas/gov/2024-07-01/examples/Transactions_Get.json b/doc/schemas/gov/2024-07-01/examples/Transactions_Get.json new file mode 100644 index 00000000000..419a42f3e75 --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/Transactions_Get.json @@ -0,0 +1,15 @@ +{ + "title": "Transactions_Get", + "operationId": "Transactions_Get", + "parameters": { + "api-version": "2024-07-01", + "transactionId": "2.42" + }, + "responses": { + "200": { + "body": { + "status": "Committed" + } + } + } +} diff --git a/doc/schemas/gov/2024-07-01/examples/Transactions_GetCommit.json b/doc/schemas/gov/2024-07-01/examples/Transactions_GetCommit.json new file mode 100644 index 00000000000..8ddf5b818d7 --- /dev/null +++ b/doc/schemas/gov/2024-07-01/examples/Transactions_GetCommit.json @@ -0,0 +1,15 @@ +{ + "title": "Transactions_GetCommit", + "operationId": "Transactions_GetCommit", + "parameters": { + "api-version": "2024-07-01" + }, + "responses": { + "200": { + "body": { + "status": "Committed", + "transactionId": "7.2385" + } + } + } +} diff --git a/doc/schemas/gov/2024-07-01/gov.json b/doc/schemas/gov/2024-07-01/gov.json new file mode 100644 index 00000000000..83162c351d4 --- /dev/null +++ b/doc/schemas/gov/2024-07-01/gov.json @@ -0,0 +1,2455 @@ +{ + "swagger": "2.0", + "info": { + "title": "CCF Governance", + "version": "2024-07-01", + "x-typespec-generated": [ + { + "emitter": "@azure-tools/typespec-autorest" + } + ] + }, + "schemes": [ + "https" + ], + "produces": [ + "application/json" + ], + "consumes": [ + "application/json" + ], + "tags": [], + "paths": { + "/gov/members/proposals": { + "get": { + "operationId": "Proposals_List", + "description": "Returns all current proposed changes to the service. Note that non-open proposals (ie - those which have already been accepted, rejected, withdrawn, etc) are not returned.", + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/PagedProposal" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction this response was read from. The service state may be altered by other write requests. Reads at the same transactionId describe a consistent single point in the service history.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "Proposals_List": { + "$ref": "./examples/Proposals_List.json" + } + }, + "x-ms-pageable": { + "nextLinkName": "nextLink" + } + } + }, + "/gov/members/proposals/{proposalId}:withdraw": { + "post": { + "operationId": "Proposals_Withdraw", + "description": "Withdraw an existing proposal. Only the original proposer is permitted to withdraw.", + "consumes": [ + "application/cose" + ], + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + }, + { + "name": "proposalId", + "in": "path", + "description": "Unique ID assigned to this proposal at its submission, by the service.", + "required": true, + "type": "string", + "pattern": "^[a-f0-9]{64}$" + }, + { + "$ref": "#/parameters/CoseSignature.body" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/Proposals.Proposal" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction where this request produced a write on the service. This uniquely identifies the submitted request, and can be used to confirm that the request becomes committed.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "Proposals_Withdraw": { + "$ref": "./examples/Proposals_Withdraw.json" + } + } + } + }, + "/gov/members/proposals/{proposalId}": { + "get": { + "operationId": "Proposals_Get", + "description": "Returns a summary of a single proposed change to the service.", + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + }, + { + "name": "proposalId", + "in": "path", + "description": "Unique ID assigned to this proposal at its submission, by the service.", + "required": true, + "type": "string", + "pattern": "^[a-f0-9]{64}$" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/Proposals.Proposal" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction this response was read from. The service state may be altered by other write requests. Reads at the same transactionId describe a consistent single point in the service history.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "Proposals_Get": { + "$ref": "./examples/Proposals_Get.json" + } + } + } + }, + "/gov/members/proposals/{proposalId}/actions": { + "get": { + "operationId": "Proposals_GetActions", + "description": "Returns actions contained in a proposal.", + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + }, + { + "name": "proposalId", + "in": "path", + "description": "Unique ID assigned to this proposal at its submission, by the service.", + "required": true, + "type": "string", + "pattern": "^[a-f0-9]{64}$" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/Proposals.ProposalActions" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction this response was read from. The service state may be altered by other write requests. Reads at the same transactionId describe a consistent single point in the service history.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "Proposals_GetActions": { + "$ref": "./examples/Proposals_GetActions.json" + } + } + } + }, + "/gov/members/proposals/{proposalId}/ballots/{memberId}:submit": { + "post": { + "operationId": "Ballots_Submit", + "description": "Submit an executable ballot for a specific proposal. This may be as simple as `return true` to vote in favour, or contain reads from the KV and conditions on the proposal contents.", + "consumes": [ + "application/cose" + ], + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + }, + { + "name": "proposalId", + "in": "path", + "description": "Unique ID assigned to this proposal at its submission, by the service.", + "required": true, + "type": "string", + "pattern": "^[a-f0-9]{64}$" + }, + { + "name": "memberId", + "in": "path", + "description": "ID of CCF member who signed and submitted this ballot.", + "required": true, + "type": "string", + "pattern": "^[a-f0-9]{64}$" + }, + { + "$ref": "#/parameters/CoseSignature.body" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/Proposals.Proposal" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction where this request produced a write on the service. This uniquely identifies the submitted request, and can be used to confirm that the request becomes committed.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "Ballots_Submit": { + "$ref": "./examples/Ballots_Submit.json" + } + } + } + }, + "/gov/members/proposals/{proposalId}/ballots/{memberId}": { + "get": { + "operationId": "Ballots_Get", + "description": "Returns a member's submitted ballot.", + "produces": [ + "text/javascript", + "application/json" + ], + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + }, + { + "name": "proposalId", + "in": "path", + "description": "Unique ID assigned to this proposal at its submission, by the service.", + "required": true, + "type": "string", + "pattern": "^[a-f0-9]{64}$" + }, + { + "name": "memberId", + "in": "path", + "description": "ID of CCF member who signed and submitted this ballot.", + "required": true, + "type": "string", + "pattern": "^[a-f0-9]{64}$" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/Proposals.Ballot" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction this response was read from. The service state may be altered by other write requests. Reads at the same transactionId describe a consistent single point in the service history.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "Ballots_Get": { + "$ref": "./examples/Ballots_Get.json" + } + } + } + }, + "/gov/members/proposals:create": { + "post": { + "operationId": "Proposals_Create", + "description": "Submit a proposed change to the service. This will be assigned an ID by the service. Submitting the same signature (including signed COSE headers such as created_at) multiple times will be treated as a single idempotent operation, returning a single created proposal (or an error if it is no longer available). Any change to the request body will be treated as a new, separate proposal.", + "consumes": [ + "application/cose" + ], + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + }, + { + "$ref": "#/parameters/CoseSignature.body" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/Proposals.Proposal" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction where this request produced a write on the service. This uniquely identifies the submitted request, and can be used to confirm that the request becomes committed.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "Proposals_Create": { + "$ref": "./examples/Proposals_Create.json" + } + } + } + }, + "/gov/members/state-digests/{memberId}:update": { + "post": { + "operationId": "StateDigests_Update", + "description": "Request that this member's stateDigest is updated to a fresher value. Only this member may update their own stateDigest. Returns the refreshed value.", + "consumes": [ + "application/cose" + ], + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + }, + { + "name": "memberId", + "in": "path", + "description": "Identifier for member this stateDigest applies to.", + "required": true, + "type": "string", + "pattern": "^[a-f0-9]{64}$" + }, + { + "$ref": "#/parameters/CoseSignature.body" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/Acks.StateDigest" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction where this request produced a write on the service. This uniquely identifies the submitted request, and can be used to confirm that the request becomes committed.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "StateDigests_Update": { + "$ref": "./examples/StateDigests_Update.json" + } + } + } + }, + "/gov/members/state-digests/{memberId}:ack": { + "post": { + "operationId": "StateDigests_Acknowledge", + "description": "Submit a signed acknowledgement of a recent digest of the service status, to transition the member to Active.", + "consumes": [ + "application/cose" + ], + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + }, + { + "name": "memberId", + "in": "path", + "description": "Identifier for member this stateDigest applies to.", + "required": true, + "type": "string", + "pattern": "^[a-f0-9]{64}$" + }, + { + "$ref": "#/parameters/CoseSignature.body" + } + ], + "responses": { + "204": { + "description": "There is no content to send for this request, but the headers may be useful. ", + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction where this request produced a write on the service. This uniquely identifies the submitted request, and can be used to confirm that the request becomes committed.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "StateDigests_Acknowledge": { + "$ref": "./examples/StateDigests_Acknowledge.json" + } + } + } + }, + "/gov/members/state-digests/{memberId}": { + "get": { + "operationId": "StateDigests_Get", + "description": "Get the stateDigest assigned to the given member, which that member must sign to become active.", + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + }, + { + "name": "memberId", + "in": "path", + "description": "Identifier for member this stateDigest applies to.", + "required": true, + "type": "string", + "pattern": "^[a-f0-9]{64}$" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/Acks.StateDigest" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction this response was read from. The service state may be altered by other write requests. Reads at the same transactionId describe a consistent single point in the service history.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "StateDigests_Get": { + "$ref": "./examples/StateDigests_Get.json" + } + } + } + }, + "/gov/recovery/encrypted-shares/{memberId}": { + "get": { + "operationId": "EncryptedShares_Get", + "description": "Retrieve a member's recovery share, encrypted with that member's share-encryption key.", + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + }, + { + "name": "memberId", + "in": "path", + "description": "ID of CCF member who this recovery share belongs to.", + "required": true, + "type": "string", + "pattern": "^[a-f0-9]{64}$" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/Recovery.EncryptedRecoveryShare" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "EncryptedShares_Get": { + "$ref": "./examples/EncryptedShares_Get.json" + } + } + } + }, + "/gov/recovery/members/{memberId}:recover": { + "post": { + "operationId": "Shares_Submit", + "description": "Provide a recovery share for the purpose of completing a service recovery.", + "consumes": [ + "application/cose" + ], + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + }, + { + "name": "memberId", + "in": "path", + "description": "Identifier for member this recovery state applies to.", + "required": true, + "type": "string", + "pattern": "^[a-f0-9]{64}$" + }, + { + "$ref": "#/parameters/CoseSignature.body" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/Recovery.RecoveryResponse" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction this response was read from. The service state may be altered by other write requests. Reads at the same transactionId describe a consistent single point in the service history.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "Shares_Submit": { + "$ref": "./examples/Shares_Submit.json" + } + } + } + }, + "/gov/service/constitution": { + "get": { + "operationId": "ServiceState_GetConstitution", + "description": "Retrieve the constitution which controls governance changes on this service.", + "produces": [ + "text/javascript", + "application/json" + ], + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/ServiceState.ConstitutionResponse" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction this response was read from. The service state may be altered by other write requests. Reads at the same transactionId describe a consistent single point in the service history.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "ServiceState_GetConstitution": { + "$ref": "./examples/ServiceState_GetConstitution.json" + } + } + } + }, + "/gov/service/info": { + "get": { + "operationId": "ServiceState_GetServiceInfo", + "description": "Returns general information about the service, including whether it is a recovery or original service.", + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/ServiceState.ServiceInfo" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction this response was read from. The service state may be altered by other write requests. Reads at the same transactionId describe a consistent single point in the service history.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "ServiceState_GetServiceInfo": { + "$ref": "./examples/ServiceState_GetServiceInfo.json" + } + } + } + }, + "/gov/service/javascript-app": { + "get": { + "operationId": "ServiceState_GetJsApp", + "description": "Retrieve details of Javascript application and execution engine.", + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/ServiceState.JsApp" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction this response was read from. The service state may be altered by other write requests. Reads at the same transactionId describe a consistent single point in the service history.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "ServiceState_GetJsApp": { + "$ref": "./examples/ServiceState_GetJsApp.json" + } + } + } + }, + "/gov/service/join-policy": { + "get": { + "operationId": "ServiceState_GetJoinPolicies", + "description": "Retrieve policy data which determines whether new nodes are permitted to join the service. This describes the hardware attestations which are acceptable to the service, demonstrating a joining node is running approved code.", + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/ServiceState.JoinPolicies" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction this response was read from. The service state may be altered by other write requests. Reads at the same transactionId describe a consistent single point in the service history.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "ServiceState_GetJoinPolicies": { + "$ref": "./examples/ServiceState_GetJoinPolicies.json" + } + } + } + }, + "/gov/service/js-modules": { + "get": { + "operationId": "ServiceState_ListJsModules", + "description": "Retrieve list of all modules constituting the current app.", + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/PagedJsModuleNames" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction this response was read from. The service state may be altered by other write requests. Reads at the same transactionId describe a consistent single point in the service history.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-pageable": { + "nextLinkName": "nextLink" + } + } + }, + "/gov/service/js-modules/{moduleName}": { + "get": { + "operationId": "ServiceState_GetJsModule", + "description": "Retrieve single module of current app, by name. Note that the moduleName path parameter (which may contain forward slashes indicating module path segments) must be URL-escaped to register as a single URL path segment. For instance '/foo/bar.js' should become '%2Ffoo%2Fbar.js'.", + "produces": [ + "text/javascript", + "application/json" + ], + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + }, + { + "name": "moduleName", + "in": "path", + "description": "Name of module, potentially including path elements.", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/ServiceState.JsModuleResponse" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction this response was read from. The service state may be altered by other write requests. Reads at the same transactionId describe a consistent single point in the service history.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + } + } + }, + "/gov/service/jwk": { + "get": { + "operationId": "ServiceState_GetJwkInfo", + "description": "Returns information about OpenID Connect identity providers.", + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/ServiceState.JwkInfo" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction this response was read from. The service state may be altered by other write requests. Reads at the same transactionId describe a consistent single point in the service history.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "ServiceState_GetJwkInfo": { + "$ref": "./examples/ServiceState_GetJwkInfo.json" + } + } + } + }, + "/gov/service/members": { + "get": { + "operationId": "ServiceState_ListMembers", + "description": "Retrieve list of all members who govern this service.", + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/PagedMember" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction this response was read from. The service state may be altered by other write requests. Reads at the same transactionId describe a consistent single point in the service history.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "ServiceState_ListMembers": { + "$ref": "./examples/ServiceState_ListMembers.json" + } + }, + "x-ms-pageable": { + "nextLinkName": "nextLink" + } + } + }, + "/gov/service/members/{memberId}": { + "get": { + "operationId": "ServiceState_GetMember", + "description": "Retrieve a single governing member, by ID.", + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + }, + { + "name": "memberId", + "in": "path", + "description": "ID of CCF member who this object refers to.", + "required": true, + "type": "string", + "pattern": "^[a-f0-9]{64}$" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/ServiceState.Member" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction this response was read from. The service state may be altered by other write requests. Reads at the same transactionId describe a consistent single point in the service history.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "ServiceState_GetMember": { + "$ref": "./examples/ServiceState_GetMember.json" + } + } + } + }, + "/gov/service/nodes": { + "get": { + "operationId": "ServiceState_ListNodes", + "description": "Retrieve list of all nodes participating in this service.", + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/PagedNode" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction this response was read from. The service state may be altered by other write requests. Reads at the same transactionId describe a consistent single point in the service history.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "ServiceState_ListNodes": { + "$ref": "./examples/ServiceState_ListNodes.json" + } + }, + "x-ms-pageable": { + "nextLinkName": "nextLink" + } + } + }, + "/gov/service/nodes/{nodeId}": { + "get": { + "operationId": "ServiceState_GetNode", + "description": "Retrieve a single node, by ID.", + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + }, + { + "name": "nodeId", + "in": "path", + "description": "ID of CCF node who this object refers to.", + "required": true, + "type": "string", + "pattern": "^[a-f0-9]{64}$" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/ServiceState.Node" + }, + "headers": { + "x-ms-ccf-transaction-id": { + "type": "string", + "description": "Identifier for transaction this response was read from. The service state may be altered by other write requests. Reads at the same transactionId describe a consistent single point in the service history.", + "pattern": "^[0-9]+\\.[0-9]+$" + } + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "ServiceState_GetNode": { + "$ref": "./examples/ServiceState_GetNode.json" + } + } + } + }, + "/gov/service/transactions/{transactionId}": { + "get": { + "operationId": "Transactions_Get", + "description": "Get status of transaction by transaction ID, to determine whether it has committed.", + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + }, + { + "name": "transactionId", + "in": "path", + "description": "Identifier of the requested transaction.", + "required": true, + "type": "string", + "pattern": "^[0-9]+\\.[0-9]+$" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/Transactions.Transaction" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "Transactions_Get": { + "$ref": "./examples/Transactions_Get.json" + } + } + } + }, + "/gov/service/transactions/commit": { + "get": { + "operationId": "Transactions_GetCommit", + "description": "Get latest committed transaction.", + "parameters": [ + { + "$ref": "#/parameters/Azure.Core.Foundations.ApiVersionParameter" + } + ], + "responses": { + "200": { + "description": "The request has succeeded.", + "schema": { + "$ref": "#/definitions/Transactions.CommittedTransaction" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/Azure.Core.Foundations.ErrorResponse" + }, + "headers": { + "x-ms-error-code": { + "type": "string", + "description": "String error code indicating what went wrong." + } + } + } + }, + "x-ms-examples": { + "Transactions_GetCommit": { + "$ref": "./examples/Transactions_GetCommit.json" + } + } + } + } + }, + "definitions": { + "Acks.StateDigest": { + "type": "object", + "description": "A compact summary of the service's state up to a certain point in time, updated and signed by members to indicate their participation in and approval of the service.", + "properties": { + "memberId": { + "$ref": "#/definitions/memberId", + "description": "Identifier for member this stateDigest applies to.", + "x-ms-mutability": [ + "read" + ] + }, + "stateDigest": { + "type": "string", + "description": "Hex-encoding of SHA-256 hash of the root of the service's merkle tree. This should be signed by a new member and submitted as an ACK to mark that member as Active.", + "pattern": "^[a-f0-9]{64}$" + } + }, + "required": [ + "memberId", + "stateDigest" + ] + }, + "Azure.Core.Foundations.Error": { + "type": "object", + "description": "The error object.", + "properties": { + "code": { + "type": "string", + "description": "One of a server-defined set of error codes." + }, + "message": { + "type": "string", + "description": "A human-readable representation of the error." + }, + "target": { + "type": "string", + "description": "The target of the error." + }, + "details": { + "type": "array", + "description": "An array of details about specific errors that led to this reported error.", + "items": { + "$ref": "#/definitions/Azure.Core.Foundations.Error" + }, + "x-ms-identifiers": [] + }, + "innererror": { + "$ref": "#/definitions/Azure.Core.Foundations.InnerError", + "description": "An object containing more specific information than the current object about the error." + } + }, + "required": [ + "code", + "message" + ] + }, + "Azure.Core.Foundations.ErrorResponse": { + "type": "object", + "description": "A response containing error details.", + "properties": { + "error": { + "$ref": "#/definitions/Azure.Core.Foundations.Error", + "description": "The error object." + } + }, + "required": [ + "error" + ] + }, + "Azure.Core.Foundations.InnerError": { + "type": "object", + "description": "An object containing more specific information about the error. As per Microsoft One API guidelines - https://github.com/Microsoft/api-guidelines/blob/vNext/Guidelines.md#7102-error-condition-responses.", + "properties": { + "code": { + "type": "string", + "description": "One of a server-defined set of error codes." + }, + "innererror": { + "$ref": "#/definitions/Azure.Core.Foundations.InnerError", + "description": "Inner error." + } + } + }, + "PagedJsModuleNames": { + "type": "object", + "description": "Paged collection of JsModuleNames items", + "properties": { + "value": { + "type": "array", + "description": "The JsModuleNames items on this page", + "items": { + "$ref": "#/definitions/ServiceState.JsModuleNames" + }, + "x-ms-identifiers": [] + }, + "nextLink": { + "type": "string", + "format": "uri", + "description": "The link to the next page of items" + } + }, + "required": [ + "value" + ] + }, + "PagedMember": { + "type": "object", + "description": "Paged collection of Member items", + "properties": { + "value": { + "type": "array", + "description": "The Member items on this page", + "items": { + "$ref": "#/definitions/ServiceState.Member" + }, + "x-ms-identifiers": [] + }, + "nextLink": { + "type": "string", + "format": "uri", + "description": "The link to the next page of items" + } + }, + "required": [ + "value" + ] + }, + "PagedNode": { + "type": "object", + "description": "Paged collection of Node items", + "properties": { + "value": { + "type": "array", + "description": "The Node items on this page", + "items": { + "$ref": "#/definitions/ServiceState.Node" + }, + "x-ms-identifiers": [] + }, + "nextLink": { + "type": "string", + "format": "uri", + "description": "The link to the next page of items" + } + }, + "required": [ + "value" + ] + }, + "PagedProposal": { + "type": "object", + "description": "Paged collection of Proposal items", + "properties": { + "value": { + "type": "array", + "description": "The Proposal items on this page", + "items": { + "$ref": "#/definitions/Proposals.Proposal" + }, + "x-ms-identifiers": [] + }, + "nextLink": { + "type": "string", + "format": "uri", + "description": "The link to the next page of items" + } + }, + "required": [ + "value" + ] + }, + "Proposals.Action": { + "type": "object", + "description": "A single step in a proposed change to the service.", + "properties": { + "name": { + "type": "string", + "description": "The name of the action to perform. This should match an action defined in the service's constitution, so that it can be invoked by the `apply` function of the constitution if the proposal is accepted." + }, + "args": { + "description": "Arguments to modify the behavior of this action. The schema is determined by the action implementation, and should be validated by a `validate` call in the constitution." + } + }, + "required": [ + "name" + ] + }, + "Proposals.Ballot": { + "type": "object", + "description": "The source script of an executable vote from a member, regarding a proposed change to the service.", + "properties": { + "script": { + "type": "string", + "description": "The script to execute, returning the voter's support of this proposal." + } + }, + "required": [ + "script" + ] + }, + "Proposals.FailureInfo": { + "type": "object", + "description": "Description of why governance execution failed.", + "properties": { + "reason": { + "type": "string", + "description": "Error message describing reason for failure." + }, + "trace": { + "type": "string", + "description": "Call stack showing where failure occurred, if available." + } + }, + "required": [ + "reason" + ] + }, + "Proposals.MemberVotes": { + "type": "object", + "description": "Each key is a memberId, and the corresponding value is the result of their ballot.", + "additionalProperties": { + "type": "boolean" + } + }, + "Proposals.Proposal": { + "type": "object", + "description": "Description of a proposed change to the service.", + "properties": { + "proposalId": { + "$ref": "#/definitions/proposalId", + "description": "Unique ID assigned to this proposal at its submission, by the service." + }, + "proposerId": { + "$ref": "#/definitions/memberId", + "description": "ID of CCF member who signed and created this proposal." + }, + "proposalState": { + "$ref": "#/definitions/Proposals.ProposalState", + "description": "Current state of this proposal." + }, + "ballotCount": { + "$ref": "#/definitions/safeuint", + "description": "Count of how many ballots have been submitted for this proposal." + }, + "finalVotes": { + "$ref": "#/definitions/Proposals.MemberVotes", + "description": "If a proposal is not open, then this contains the result of each ballot when the proposal transitioned from open." + }, + "voteFailures": { + "$ref": "#/definitions/Proposals.VoteFailures", + "description": "This will be populated with a description of any ballots which failed to execute." + }, + "failure": { + "$ref": "#/definitions/Proposals.FailureInfo", + "description": "If proposalState is Failure, then this will describe why the proposal failed." + } + }, + "required": [ + "proposalId", + "proposerId", + "proposalState", + "ballotCount" + ] + }, + "Proposals.ProposalActions": { + "type": "object", + "description": "The actions contained in a proposal, describing the proposal's changes.", + "properties": { + "actions": { + "type": "array", + "description": "A list of actions to apply. Each action is considered, in order, for both proposal and execution of the proposal. All actions are validated and, if the proposal is accepted, applied atomically.", + "items": { + "$ref": "#/definitions/Proposals.Action" + }, + "x-ms-identifiers": [] + } + }, + "required": [ + "actions" + ] + }, + "Proposals.ProposalState": { + "type": "string", + "description": "Possible states for a proposal.", + "enum": [ + "Open", + "Accepted", + "Withdrawn", + "Rejected", + "Failed", + "Dropped" + ], + "x-ms-enum": { + "name": "ProposalState", + "modelAsString": true, + "values": [ + { + "name": "Open", + "value": "Open", + "description": "Proposal is active and can be voted on." + }, + { + "name": "Accepted", + "value": "Accepted", + "description": "Proposal passed a successful vote and was enacted." + }, + { + "name": "Withdrawn", + "value": "Withdrawn", + "description": "Proposal was removed by proposing member. Will never be enacted." + }, + { + "name": "Rejected", + "value": "Rejected", + "description": "Proposal was rejected by vote. Will never be enacted." + }, + { + "name": "Failed", + "value": "Failed", + "description": "Proposal passed a successful vote, but its proposed actions failed. Will never be enacted." + }, + { + "name": "Dropped", + "value": "Dropped", + "description": "Proposal was open when its semantics were potentially changed (code or constitution were modified), so it was automatically invalidated." + } + ] + } + }, + "Proposals.VoteFailures": { + "type": "object", + "description": "Each key is a memberId, and the corresponding value explains why execution of their ballot failed.", + "additionalProperties": { + "$ref": "#/definitions/Proposals.FailureInfo" + } + }, + "Recovery.EncryptedRecoveryShare": { + "type": "object", + "description": "A share of a recovery key, granted for a specific recovery member, and encrypted with that member's share-encryption key. This is safe to share in the ledger or amongst untrusted callers, as only the intended member will be able to decrypt and access the secret content.", + "properties": { + "encryptedShare": { + "type": "string", + "format": "byte", + "description": "Base-64 encoding of a member's encrypted share." + } + }, + "required": [ + "encryptedShare" + ] + }, + "Recovery.Member": { + "type": "object", + "description": "Recovery-specific details for a given member." + }, + "Recovery.RecoveryResponse": { + "type": "object", + "description": "Response to a submitted recovery share.", + "properties": { + "message": { + "type": "string", + "description": "Human-readable description of current recovery progress." + }, + "submittedCount": { + "$ref": "#/definitions/safeuint", + "description": "Count of how many accepted member shares have been submitted, including the current request." + }, + "recoveryThreshold": { + "$ref": "#/definitions/safeuint", + "description": "Count of how many member shares are required to initiate the end-of-recovery procedure." + } + }, + "required": [ + "message", + "submittedCount", + "recoveryThreshold" + ] + }, + "Recovery.RecoveryShare": { + "type": "object", + "description": "Container for a member's raw recovery share. This should be carefully guarded, and only submitted to a trusted service over a secure channel, for the purposes of recovery.", + "properties": { + "share": { + "type": "string", + "format": "byte", + "description": "Base-64 encoding of a member's raw recovery share (unencrypted)." + } + }, + "required": [ + "share" + ] + }, + "ServiceState.ConstitutionResponse": { + "type": "object", + "description": "Constitution used to make governance decisions on the service. All governance changes are presented as proposals which must be validated, approved, and applied by the code in this constitution.", + "properties": { + "constitution": { + "type": "string", + "description": "Javascript source code of constitution." + } + }, + "required": [ + "constitution" + ] + }, + "ServiceState.FeedInfo": { + "type": "object", + "description": "Collection of claims regarding a specific feed.", + "properties": { + "svn": { + "type": "string", + "description": "Security version number claimed by this endorser." + } + }, + "required": [ + "svn" + ] + }, + "ServiceState.ForwardingRequired": { + "type": "string", + "description": "Describes the forwarding behavior of a specific endpoint. Write requests cannot be executed on a backup, so will generally be forwarded by any backup node which receives them to the current primary. Future requests on the same session may then be forwarded to maintain session consistency.", + "enum": [ + "Sometimes", + "Always", + "Never" + ], + "x-ms-enum": { + "name": "ForwardingRequired", + "modelAsString": true, + "values": [ + { + "name": "Sometimes", + "value": "Sometimes", + "description": "Indicates that this request should be forwarded if-and-only-if it is needed to maintain session consistency. If stale reads are acceptable then they can be completed on a backup, and the request will not be forwarded. This should be the default behavior for read-only endpoints." + }, + { + "name": "Always", + "value": "Always", + "description": "Indicates that this request should always be forwarded. This will trigger forwarding of any additional requests on the same session, even those marked ForwardRequired::Sometimes. This should be the default behavior for any endpoint which writes to the Key-Value store." + }, + { + "name": "Never", + "value": "Never", + "description": "Indicates endpoints which will never be forwarded, even when this will result in a break of session consistency. This should be used only to access node-local information, or when weaker consistency is acceptable." + } + ] + } + }, + "ServiceState.JoinPolicies": { + "type": "object", + "description": "Collection of all policies which determine currently acceptable nodes, across multiple platforms.", + "properties": { + "sgx": { + "$ref": "#/definitions/ServiceState.JoinPolicy", + "description": "Policy applied to nodes running in SGX enclaves." + }, + "snp": { + "$ref": "#/definitions/ServiceState.SnpJoinPolicy", + "description": "Policy applied to nodes running in AMD SEV-SNP containers." + } + }, + "required": [ + "sgx", + "snp" + ] + }, + "ServiceState.JoinPolicy": { + "type": "object", + "description": "Describes what a joining node must present, in order to join the service.", + "properties": { + "measurements": { + "type": "array", + "description": "Code measurements of acceptable enclaves.", + "items": { + "type": "string", + "format": "byte" + } + } + }, + "required": [ + "measurements" + ] + }, + "ServiceState.JsApp": { + "type": "object", + "description": "Describes the currently installed JavaScript application.", + "properties": { + "endpoints": { + "type": "object", + "description": "The collection of endpoints exposed by the application. Keyed by path.", + "additionalProperties": { + "$ref": "#/definitions/ServiceState.JsOperations" + } + } + }, + "required": [ + "endpoints" + ] + }, + "ServiceState.JsEndpointInfo": { + "type": "object", + "description": "Describes an endpoint implemented by a Javascript handler.", + "properties": { + "jsModule": { + "type": "string", + "description": "The name of the module where the endpoint function is located." + }, + "jsFunction": { + "type": "string", + "description": "The name of the exported function which implements this endpoint." + }, + "forwardingRequired": { + "$ref": "#/definitions/ServiceState.ForwardingRequired", + "description": "Describes whether requests to this endpoint should be forwarded to the primary or executed on backups." + }, + "authnPolicies": { + "type": "array", + "description": "The authentication policies which restrict access to this endpoint", + "items": { + "type": "string" + } + }, + "mode": { + "$ref": "#/definitions/ServiceState.JsExecMode", + "description": "Describes how this endpoint should be executed." + }, + "openApi": { + "type": "object", + "description": "An OpenAPI Operation object (https://swagger.io/specification/#operation-object) describing this operation. This is merged into the auto-generated OpenAPI to describe the current application's API.", + "additionalProperties": {} + } + }, + "required": [ + "jsModule", + "jsFunction", + "forwardingRequired", + "authnPolicies", + "mode", + "openApi" + ] + }, + "ServiceState.JsExecMode": { + "type": "string", + "description": "Describes the execution requirements of a specific endpoint.", + "enum": [ + "ReadWrite", + "ReadOnly", + "Historical" + ], + "x-ms-enum": { + "name": "JsExecMode", + "modelAsString": true, + "values": [ + { + "name": "ReadWrite", + "value": "ReadWrite", + "description": "Indicates that the endpoint does (or may) produces writes to the Key-Value store." + }, + { + "name": "ReadOnly", + "value": "ReadOnly", + "description": "Indicates that the endpoint is a pure read, and will never write to the Key-Value store. Note that this includes endpoints which only access node-local state, and do not read from the Key-Value store at all." + }, + { + "name": "Historical", + "value": "Historical", + "description": "Indicates that the endpoint operates over a historical write to the Key-Value store rather than the latest, current state. These endpoints are also read-only, and may not produce writes." + } + ] + } + }, + "ServiceState.JsModuleNames": { + "type": "object", + "description": "Names of JS modules implementing the current app.", + "properties": { + "moduleName": { + "type": "string", + "description": "Name of module, potentially including path elements.", + "x-ms-mutability": [ + "read" + ] + } + }, + "required": [ + "moduleName" + ] + }, + "ServiceState.JsModuleResponse": { + "type": "object", + "description": "JavaScript source code corresponding to a given module name.", + "properties": { + "source": { + "type": "string", + "description": "JavaScript source code of this module." + } + }, + "required": [ + "source" + ] + }, + "ServiceState.JsOperations": { + "type": "object", + "description": "The collection of operations available on each path. Keyed by HTTP method.", + "additionalProperties": { + "$ref": "#/definitions/ServiceState.JsEndpointInfo" + } + }, + "ServiceState.Jwk": { + "type": "object", + "description": "Describes a single JWK.", + "properties": { + "certificate": { + "$ref": "#/definitions/ServiceState.pem", + "description": "x509 cert used to validate claims made by this key." + }, + "issuer": { + "type": "string", + "description": "Issuer ID of entity who issued this key." + } + }, + "required": [ + "certificate" + ] + }, + "ServiceState.JwkInfo": { + "type": "object", + "description": "Describes what Javascript Web Tokens (JWTs) are accepted by the service, and how they will be validated.", + "properties": { + "issuers": { + "type": "object", + "description": "Collection of JWT issuers. Keyed by issuer ID.", + "additionalProperties": { + "$ref": "#/definitions/ServiceState.JwtIssuer" + } + }, + "caCertBundles": { + "type": "object", + "description": "Collection of CAs used to authenticate connections with issuers. Keyed by governance-controlled bundle names.", + "additionalProperties": { + "$ref": "#/definitions/ServiceState.caCertBundle" + } + }, + "keys": { + "type": "object", + "description": "Collection of retrieved JWKs. Keyed by kid.", + "additionalProperties": { + "$ref": "#/definitions/ServiceState.Jwk" + } + } + }, + "required": [ + "issuers", + "caCertBundles", + "keys" + ] + }, + "ServiceState.JwtIssuer": { + "type": "object", + "description": "Description of a JWT issuer or identity provider that the current service will trust tokens from.", + "properties": { + "keyFilter": { + "$ref": "#/definitions/ServiceState.JwtIssuerKeyFilter", + "description": "Adds restrictions on whether keys should be accepted from this issuer." + }, + "keyPolicy": { + "type": "object", + "description": "Collection of claims which must be present in SGX attestation to permit updates from this issuer.", + "additionalProperties": { + "type": "string" + } + }, + "autoRefresh": { + "type": "boolean", + "description": "Whether this issuer's keys are periodically refreshed with a fetch from the current primary. If false, these will only be updated by governance." + }, + "caCertBundleName": { + "type": "string", + "description": "Name of bundle used to authenticate issuer when auto-refreshing." + } + }, + "required": [ + "keyFilter", + "autoRefresh" + ] + }, + "ServiceState.JwtIssuerKeyFilter": { + "type": "string", + "description": "Possible restrictions on what keys will be accepted from a JWT issuer.", + "enum": [ + "All", + "Sgx" + ], + "x-ms-enum": { + "name": "JwtIssuerKeyFilter", + "modelAsString": true, + "values": [ + { + "name": "All", + "value": "All", + "description": "Accepts any JWT issuer." + }, + { + "name": "Sgx", + "value": "Sgx", + "description": "Only accepts JWTs issued by a token provider running in SGX, which provides a suitable attestation and additional claims." + } + ] + } + }, + "ServiceState.Member": { + "type": "object", + "description": "Information on individual members within a consortium.", + "properties": { + "memberId": { + "$ref": "#/definitions/memberId", + "description": "ID of CCF member who this object refers to." + }, + "status": { + "$ref": "#/definitions/ServiceState.MemberStatus", + "description": "Current status of this member." + }, + "memberData": { + "description": "Arbitrary service-defined metadata about this member. May be used by constitution or application code, but will not affect any core framework decisions." + }, + "certificate": { + "$ref": "#/definitions/ServiceState.pem", + "description": "x509 certificate used as this member's identity." + }, + "publicEncryptionKey": { + "$ref": "#/definitions/ServiceState.pem", + "description": "x509 key used to encrypt this member's key shares, if they are a recovery member." + } + }, + "required": [ + "memberId", + "status", + "certificate" + ] + }, + "ServiceState.MemberStatus": { + "type": "string", + "description": "Possible states for a CCF governing member.", + "enum": [ + "Accepted", + "Active" + ], + "x-ms-enum": { + "name": "MemberStatus", + "modelAsString": true, + "values": [ + { + "name": "Accepted", + "value": "Accepted", + "description": "Member has been approved to join the service, but have not yet submitted an ACK to indicate their participation. These members should not be considered by constitutions in quorum calculations, and their signed requests will be rejected until they become Active." + }, + { + "name": "Active", + "value": "Active", + "description": "Member has submitted a valid ACK and is a full voting participant." + } + ] + } + }, + "ServiceState.NetworkInterface": { + "type": "object", + "description": "Details of how to contact a CCF node. Each node may listen on multiple interfaces, for different kinds of traffic.", + "properties": { + "publishedAddress": { + "type": "string", + "description": "The network address where this node believes it is publicly accessible, in the format [:]." + }, + "protocol": { + "type": "string", + "description": "The application layer protocol which the node expects on this interface. Currently supports \"http1\" and \"http2\", more protocols may be added in future." + } + }, + "required": [ + "publishedAddress", + "protocol" + ] + }, + "ServiceState.Node": { + "type": "object", + "description": "Information on individual nodes within a service.", + "properties": { + "nodeId": { + "$ref": "#/definitions/nodeId", + "description": "ID of CCF node who this object refers to." + }, + "status": { + "$ref": "#/definitions/ServiceState.NodeStatus", + "description": "Current status of this node." + }, + "nodeData": { + "description": "Arbitrary service-defined metadata about this node. May be used by constitution or application code, but will not affect any core framework decisions." + }, + "certificate": { + "$ref": "#/definitions/ServiceState.pem", + "description": "x509 certificate containing this node's identity." + }, + "retiredCommitted": { + "type": "boolean", + "description": "This is false during node's normal operation. It transitions to true once the node has been retired, and that retirement has been committed by the service. At this point it is safe to terminate a node. Terminating a node any earlier may affect liveness of the service." + }, + "quoteInfo": { + "$ref": "#/definitions/ServiceState.QuoteInfo", + "description": "Contains this node's hardware attestation. This is generated during node startup, and must meet the current join policy restrictions for the node to successfully join a service." + }, + "rpcInterfaces": { + "type": "object", + "description": "A collection of interfaces by which this node may be contacted. Some may be limited to private networks, and others may be DNS names or internet-public network addresses. The keys are arbitrary strings determined by the node operator.", + "additionalProperties": { + "$ref": "#/definitions/ServiceState.NetworkInterface" + } + } + }, + "required": [ + "nodeId", + "status", + "certificate", + "retiredCommitted", + "quoteInfo", + "rpcInterfaces" + ] + }, + "ServiceState.NodeStatus": { + "type": "string", + "description": "Lifecycle state of a CCF node. Nodes will generally start as Pending, then transition to Trusted, then to Retired. They are only full participants in the service while they are Trusted.", + "enum": [ + "Pending", + "Trusted", + "Retired" + ], + "x-ms-enum": { + "name": "NodeStatus", + "modelAsString": true, + "values": [ + { + "name": "Pending", + "value": "Pending", + "description": "Indicates a node which has successfully completed a join request to the service (including attestation checks), but has not yet been approved by governance." + }, + { + "name": "Trusted", + "value": "Trusted", + "description": "Indicates a node which has been approved by governance, and is a full participant in the service." + }, + { + "name": "Retired", + "value": "Retired", + "description": "Indicates a node which has been removed from a service by a reconfiguration." + } + ] + } + }, + "ServiceState.QuoteInfo": { + "type": "object", + "description": "Common type for attestation information, describing the cryptographically-endorsed claim of what code is executing, and what platform it is executing on. Derived types contain platform-specific details.", + "properties": { + "format": { + "type": "string", + "description": "Discriminator property for QuoteInfo." + } + }, + "discriminator": "format", + "required": [ + "format" + ] + }, + "ServiceState.ServiceInfo": { + "type": "object", + "description": "General information about the current service.", + "properties": { + "status": { + "$ref": "#/definitions/ServiceState.ServiceStatus", + "description": "Lifetime stage of the service." + }, + "certificate": { + "$ref": "#/definitions/ServiceState.pem", + "description": "The current service identity. This is the public face of a secret key shared only by the nodes within the service, and should be used to authenticate TLS sessions with this service." + }, + "recoveryCount": { + "$ref": "#/definitions/safeuint", + "description": "Records how many predecessors this service has. While the service identity certificate will change on any recovery, this allows users to determine exactly how many such recoveries have occurred." + }, + "creationTransactionId": { + "$ref": "#/definitions/transactionId", + "description": "Transaction ID at which this service was first created. If this is a recovery of a previous service, this will indicate when the current service was recovered." + }, + "previousServiceCreationTransactionId": { + "$ref": "#/definitions/transactionId", + "description": "Transaction ID at which the predecessor service was created, if this service is a recovery. If this is an original service rather than a recovery, this will be omitted." + }, + "serviceData": { + "description": "Arbitrary service-defined metadata about this service. May be used by constitution or application code, but will not affect any core framework decisions." + }, + "configuration": { + "type": "object", + "description": "Lists governance-controlled configuration parameters of this service, which will be used by core framework code.", + "properties": { + "maximumNodeCertificateValidityDays": { + "$ref": "#/definitions/safeuint" + }, + "recentCoseProposalsWindowSize": { + "$ref": "#/definitions/safeuint" + } + }, + "required": [ + "maximumNodeCertificateValidityDays", + "recentCoseProposalsWindowSize" + ] + } + }, + "required": [ + "status", + "certificate", + "recoveryCount", + "creationTransactionId", + "configuration" + ] + }, + "ServiceState.ServiceStatus": { + "type": "string", + "description": "State machine values for current service lifetime. New services start in Opening, and transition to Open via a governance proposal. They will only accept user transactions on the `/app` endpoints once they are Open. Recovery services have additional states where they must wait for members to submit sufficient recovery shares to access the previous ledger secrets, and while they are decrypting and replaying the previous ledger contents.", + "enum": [ + "Opening", + "Open", + "WaitingForRecoveryShares", + "Recovering" + ], + "x-ms-enum": { + "name": "ServiceStatus", + "modelAsString": true, + "values": [ + { + "name": "Opening", + "value": "Opening", + "description": "Services which have not yet passed a `transition_service_to_open` proposal." + }, + { + "name": "Open", + "value": "Open", + "description": "Services which are operating normally and accepting user transactions." + }, + { + "name": "WaitingForRecoveryShares", + "value": "WaitingForRecoveryShares", + "description": "Recovered services which cannot yet access private state." + }, + { + "name": "Recovering", + "value": "Recovering", + "description": "Recovered services which are actively replaying transactions from previous service, to reach the same state." + } + ] + } + }, + "ServiceState.SgxQuoteInfo": { + "type": "object", + "description": "Attestation information for Intel SGX enclaves.", + "properties": { + "quote": { + "type": "string", + "format": "byte", + "description": "Base-64 encoded SGX quote." + }, + "endorsements": { + "type": "string", + "format": "byte", + "description": "Base-64 encoded SGX endorsements." + } + }, + "required": [ + "quote", + "endorsements" + ], + "allOf": [ + { + "$ref": "#/definitions/ServiceState.QuoteInfo" + } + ], + "x-ms-discriminator-value": "OE_SGX_v1" + }, + "ServiceState.SnpJoinPolicy": { + "type": "object", + "description": "Join policy fields specific to nodes running on AMD SEV-SNP hardware.", + "properties": { + "measurements": { + "type": "array", + "description": "Code measurements of acceptable enclaves.", + "items": { + "type": "string", + "format": "byte" + } + }, + "hostData": { + "type": "object", + "description": "Collection of acceptable host data values.", + "additionalProperties": { + "format": "byte", + "type": "string" + } + }, + "uvmEndorsements": { + "type": "object", + "description": "Collection of acceptable UVM endorsements. Keyed by endorser's did.", + "additionalProperties": { + "$ref": "#/definitions/ServiceState.UvmEndorsementFeeds" + } + } + }, + "required": [ + "measurements", + "hostData", + "uvmEndorsements" + ] + }, + "ServiceState.SnpQuoteInfo": { + "type": "object", + "description": "Attestation information for AMD SEV-SNP containers.", + "properties": { + "uvmEndorsements": { + "type": "string", + "format": "byte", + "description": "Base-64 encoded SNP UVM endorsements." + }, + "endorsedTcb": { + "type": "string", + "format": "byte", + "description": "Base-64 encoded SNP TCB endorsements." + } + }, + "required": [ + "uvmEndorsements", + "endorsedTcb" + ], + "allOf": [ + { + "$ref": "#/definitions/ServiceState.QuoteInfo" + } + ], + "x-ms-discriminator-value": "AMD_SEV_SNP_v1" + }, + "ServiceState.UvmEndorsementFeeds": { + "type": "object", + "description": "Collection of endorsement feeds, keyed by feed name.", + "additionalProperties": { + "$ref": "#/definitions/ServiceState.FeedInfo" + } + }, + "ServiceState.caCertBundle": { + "type": "string", + "description": "Chain of endorsed certificates (PEM format) leading to a CA." + }, + "ServiceState.pem": { + "type": "string", + "description": "PEM encoding of a cryptographic identifier. Contains a base64-encoded payload wrapped in content type identifiers." + }, + "Transactions.CommittedTransaction": { + "type": "object", + "description": "Description of latest committed transaction.", + "properties": { + "transactionId": { + "$ref": "#/definitions/transactionId", + "description": "Identifier of committed transaction." + }, + "status": { + "$ref": "#/definitions/Transactions.TransactionStatus", + "description": "Status of this transaction." + } + }, + "required": [ + "transactionId", + "status" + ] + }, + "Transactions.NamedTransaction": { + "type": "object", + "description": "Description of a named transaction's current state.", + "properties": { + "status": { + "$ref": "#/definitions/Transactions.TransactionStatus", + "description": "Status of this transaction." + } + }, + "required": [ + "status" + ] + }, + "Transactions.Transaction": { + "type": "object", + "description": "Common transaction information.", + "properties": { + "status": { + "$ref": "#/definitions/Transactions.TransactionStatus", + "description": "Status of this transaction." + } + }, + "required": [ + "status" + ] + }, + "Transactions.TransactionStatus": { + "type": "string", + "description": "Possible states for a CCF transaction. See docs for details: https://microsoft.github.io/CCF/main/use_apps/verify_tx.html#checking-for-commit", + "enum": [ + "Unknown", + "Pending", + "Committed", + "Invalid" + ], + "x-ms-enum": { + "name": "TransactionStatus", + "modelAsString": true, + "values": [ + { + "name": "Unknown", + "value": "Unknown", + "description": "This is not a transaction the current node knows, but could exist in future. This may be returned when a transaction is created on one node then immediately queried on another, before it has been replicated." + }, + { + "name": "Pending", + "value": "Pending", + "description": "This transaction is known on the current node, but has not yet been committed. This is expected to be a temporary state." + }, + { + "name": "Committed", + "value": "Committed", + "description": "This transaction is known on the current node, and known to be committed. This means it has been replicated to a quorum of nodes, so will persist through future elections. Committed is a terminal state of this state machine." + }, + { + "name": "Invalid", + "value": "Invalid", + "description": "This transaction ID will never commit in the current service, because it contains a different term than a known transaction with the same sequence number. This can occur for a transaction ID returned from the service (ie - which was previously Unknown or Pending), if that transaction is lost during a consensus election. This should be rare. Invalid is a terminal state of this state machine." + } + ] + } + }, + "Versions": { + "type": "string", + "enum": [ + "2024-07-01" + ], + "x-ms-enum": { + "name": "Versions", + "modelAsString": true + } + }, + "memberId": { + "type": "string", + "description": "Hex encoding of SHA-256 of a member certificate's fingerprint.", + "pattern": "^[a-f0-9]{64}$" + }, + "nodeId": { + "type": "string", + "description": "Hex encoding of SHA-256 of a node's public key.", + "pattern": "^[a-f0-9]{64}$" + }, + "proposalId": { + "type": "string", + "description": "Hex encoding of SHA-256 of proposed actions and merkle root of store at proposal creation. Unlike other IDs, this is generated on the service and will not be known in advance.", + "pattern": "^[a-f0-9]{64}$" + }, + "safeuint": { + "type": "integer", + "format": "int64", + "description": "A non-negative JSON-safe integer (ie max is 2^53 - 1)", + "minimum": 0 + }, + "transactionId": { + "type": "string", + "description": "Uniquely identifies an atomic transaction within a CCF service. Composed of a term number and sequence number. Sequence numbers increase monotonically, apart from during elections where the service may reuse an existing sequence number. Each election will result in a new, higher term number being used for the conflicting and future sequence numbers.", + "pattern": "^[0-9]+\\.[0-9]+$" + }, + "userId": { + "type": "string", + "description": "Hex encoding of SHA-256 of user certificate's fingerprint.", + "pattern": "^[a-f0-9]{64}$" + } + }, + "parameters": { + "Azure.Core.Foundations.ApiVersionParameter": { + "name": "api-version", + "in": "query", + "description": "The API version to use for this operation.", + "required": true, + "type": "string", + "minLength": 1, + "x-ms-parameter-location": "method", + "x-ms-client-name": "apiVersion" + }, + "CoseSignature.body": { + "name": "body", + "in": "body", + "description": "A raw CoseSign1 signature. See CCF docs for required headers and body schema: https://microsoft.github.io/CCF/main/use_apps/issue_commands.html#cose-schemas", + "required": true, + "schema": { + "type": "string", + "format": "binary" + }, + "x-ms-parameter-location": "method" + } + } +} diff --git a/src/node/gov/api_schema.h.in b/src/node/gov/api_schema.h.in index 542da7f1977..03b2d644a3b 100644 --- a/src/node/gov/api_schema.h.in +++ b/src/node/gov/api_schema.h.in @@ -18,6 +18,9 @@ namespace ccf::gov::endpoints::schema static constexpr auto v2023_06_01_preview = R"!!!(@GOV_API_SCHEMA_2023_06_01_PREVIEW@)!!!"; + static constexpr auto v2024_07_01 = + R"!!!(@GOV_API_SCHEMA_2024_07_01@)!!!"; + #pragma clang diagnostic pop // clang-format on diff --git a/src/node/gov/api_version.h b/src/node/gov/api_version.h index ff7e5563539..76ecf53d075 100644 --- a/src/node/gov/api_version.h +++ b/src/node/gov/api_version.h @@ -12,30 +12,38 @@ namespace ccf::gov::endpoints enum class ApiVersion { preview_v1, + MIN = preview_v1, + + v1, }; static constexpr std::pair api_version_strings[] = { - {ApiVersion::preview_v1, "2023-06-01-preview"}}; + {ApiVersion::preview_v1, "2023-06-01-preview"}, + {ApiVersion::v1, "2024-07-01"}}; std::optional get_api_version( - ccf::endpoints::CommandEndpointContext& ctx) + ccf::endpoints::CommandEndpointContext& ctx, + ApiVersion min_accepted, + // Optional out-parameter indicating why API version wasn't found + const char** error_code = nullptr) { - static std::string accepted_versions_suffix = ""; - if (accepted_versions_suffix.empty()) + std::string accepted_versions_suffix = "The supported api-versions are: "; + auto first = true; + for (const auto& p : api_version_strings) { - accepted_versions_suffix = "The supported api-versions are: "; - auto first = true; - for (const auto& p : api_version_strings) + if (p.first < min_accepted) + { + continue; + } + + if (first) + { + accepted_versions_suffix += p.second; + first = false; + } + else { - if (first) - { - accepted_versions_suffix += p.second; - first = false; - } - else - { - accepted_versions_suffix += fmt::format(", {}", p.second); - } + accepted_versions_suffix += fmt::format(", {}", p.second); } } @@ -53,6 +61,10 @@ namespace ccf::gov::endpoints "requests. {}", param_name, accepted_versions_suffix)); + if (error_code != nullptr) + { + *error_code = ccf::errors::MissingApiVersionParameter; + } return std::nullopt; } @@ -60,7 +72,7 @@ namespace ccf::gov::endpoints std::begin(api_version_strings), std::end(api_version_strings), [&qit](const auto& p) { return p.second == qit->second; }); - if (it == std::end(api_version_strings)) + if (it == std::end(api_version_strings) || it->first < min_accepted) { auto message = fmt::format( "Unsupported api-version '{}'. {}", @@ -70,6 +82,10 @@ namespace ccf::gov::endpoints HTTP_STATUS_BAD_REQUEST, ccf::errors::UnsupportedApiVersionValue, std::move(message)); + if (error_code != nullptr) + { + *error_code = ccf::errors::UnsupportedApiVersionValue; + } return std::nullopt; } @@ -82,10 +98,10 @@ namespace ccf::gov::endpoints // without validating the given API version, so long as the behaviour is the // same for *all* accepted versions. template - auto api_version_adapter(Fn&& f) + auto api_version_adapter(Fn&& f, ApiVersion min_accepted = ApiVersion::MIN) { - return [f](auto& ctx) { - const auto api_version = get_api_version(ctx); + return [f, min_accepted](auto& ctx) { + const auto api_version = get_api_version(ctx, min_accepted); if (api_version.has_value()) { f(ctx, api_version.value()); diff --git a/src/node/gov/gov_endpoint_registry.h b/src/node/gov/gov_endpoint_registry.h index e01fef55b72..1445bd784ca 100644 --- a/src/node/gov/gov_endpoint_registry.h +++ b/src/node/gov/gov_endpoint_registry.h @@ -73,7 +73,10 @@ namespace ccf void api_endpoint(ccf::endpoints::ReadOnlyEndpointContext& ctx) override { using namespace ccf::gov::endpoints; - const auto api_version = get_api_version(ctx); + + const char* error_code = nullptr; + const auto api_version = + get_api_version(ctx, ApiVersion::MIN, &error_code); if (api_version.has_value()) { switch (api_version.value()) @@ -87,10 +90,27 @@ namespace ccf ctx.rpc_ctx->set_response_status(HTTP_STATUS_OK); break; } + case ApiVersion::v1: + { + ctx.rpc_ctx->set_response_body(schema::v2024_07_01); + ctx.rpc_ctx->set_response_header( + http::headers::CONTENT_TYPE, + http::headervalues::contenttype::JSON); + ctx.rpc_ctx->set_response_status(HTTP_STATUS_OK); + break; + } } } else { + // If an _invalid_ API version was passed, then an error response has + // already been populated + if (error_code == ccf::errors::UnsupportedApiVersionValue) + { + return; + } + + // Else (API version parameter was missing) return the classic API CommonEndpointRegistry::api_endpoint(ctx); } } diff --git a/src/node/gov/handlers/acks.h b/src/node/gov/handlers/acks.h index 5a445864671..7e50f1af290 100644 --- a/src/node/gov/handlers/acks.h +++ b/src/node/gov/handlers/acks.h @@ -19,6 +19,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { // Get memberId from path parameter @@ -74,6 +75,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { // Get memberId from path parameter @@ -161,6 +163,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { // Get memberId from path parameter diff --git a/src/node/gov/handlers/proposals.h b/src/node/gov/handlers/proposals.h index 50d8ae689eb..239008f9f15 100644 --- a/src/node/gov/handlers/proposals.h +++ b/src/node/gov/handlers/proposals.h @@ -394,6 +394,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { const auto& cose_ident = @@ -664,6 +665,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { const auto& cose_ident = @@ -758,6 +760,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { ccf::ProposalId proposal_id; @@ -801,6 +804,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { auto proposal_info_handle = @@ -838,6 +842,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { ccf::ProposalId proposal_id; @@ -882,6 +887,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { const auto& cose_ident = @@ -1054,6 +1060,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { ccf::ProposalId proposal_id; diff --git a/src/node/gov/handlers/recovery.h b/src/node/gov/handlers/recovery.h index 71bdc3559c6..52d64284bbd 100644 --- a/src/node/gov/handlers/recovery.h +++ b/src/node/gov/handlers/recovery.h @@ -19,6 +19,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { ccf::MemberId member_id; @@ -64,6 +65,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { if ( diff --git a/src/node/gov/handlers/service_state.h b/src/node/gov/handlers/service_state.h index e2c440a1d08..b74aa79c87f 100644 --- a/src/node/gov/handlers/service_state.h +++ b/src/node/gov/handlers/service_state.h @@ -142,6 +142,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { auto constitution_handle = @@ -181,6 +182,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { auto response_body = nlohmann::json::object(); @@ -272,6 +274,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { auto response_body = nlohmann::json::object(); @@ -325,7 +328,108 @@ namespace ccf::gov::endpoints .make_read_only_endpoint( "/service/javascript-app", HTTP_GET, - api_version_adapter(get_javascript_app), + api_version_adapter(get_javascript_app, ApiVersion::v1), + no_auth_required) + .set_openapi_hidden(true) + .install(); + + auto get_javascript_modules = [&](auto& ctx, ApiVersion api_version) { + switch (api_version) + { + case ApiVersion::preview_v1: + case ApiVersion::v1: + default: + { + auto response_body = nlohmann::json::object(); + + { + auto module_list = nlohmann::json::array(); + + auto modules_handle = + ctx.tx.template ro(ccf::Tables::MODULES); + + modules_handle->foreach_key( + [&module_list](const std::string& module_name) { + auto entry = nlohmann::json::object(); + entry["moduleName"] = module_name; + module_list.push_back(entry); + return true; + }); + + response_body["value"] = module_list; + } + + ctx.rpc_ctx->set_response_json(response_body, HTTP_STATUS_OK); + return; + } + } + }; + registry + .make_read_only_endpoint( + "/service/javascript-modules", + HTTP_GET, + api_version_adapter(get_javascript_modules, ApiVersion::v1), + no_auth_required) + .set_openapi_hidden(true) + .install(); + + auto get_javascript_module_by_name = + [&](auto& ctx, ApiVersion api_version) { + switch (api_version) + { + case ApiVersion::preview_v1: + case ApiVersion::v1: + default: + { + std::string module_name; + { + std::string error; + if (!ccf::endpoints::get_path_param( + ctx.rpc_ctx->get_request_path_params(), + "moduleName", + module_name, + error)) + { + detail::set_gov_error( + ctx.rpc_ctx, + HTTP_STATUS_BAD_REQUEST, + ccf::errors::InvalidResourceName, + std::move(error)); + return; + } + } + + module_name = ::http::url_decode(module_name); + + auto modules_handle = + ctx.tx.template ro(ccf::Tables::MODULES); + auto module = modules_handle->get(module_name); + + if (!module.has_value()) + { + detail::set_gov_error( + ctx.rpc_ctx, + HTTP_STATUS_NOT_FOUND, + ccf::errors::ResourceNotFound, + fmt::format("Module {} does not exist.", module_name)); + return; + } + + // Return raw JS module content in body + ctx.rpc_ctx->set_response_status(HTTP_STATUS_OK); + ctx.rpc_ctx->set_response_body(std::move(module.value())); + ctx.rpc_ctx->set_response_header( + ccf::http::headers::CONTENT_TYPE, + http::headervalues::contenttype::JAVASCRIPT); + return; + } + } + }; + registry + .make_read_only_endpoint( + "/service/javascript-modules/{moduleName}", + HTTP_GET, + api_version_adapter(get_javascript_module_by_name, ApiVersion::v1), no_auth_required) .set_openapi_hidden(true) .install(); @@ -334,6 +438,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { auto response_body = nlohmann::json::object(); @@ -424,6 +529,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { auto response_body = nlohmann::json::object(); @@ -531,6 +637,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { auto response_body = nlohmann::json::object(); @@ -579,6 +686,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { ccf::MemberId member_id; @@ -630,6 +738,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { auto response_body = nlohmann::json::object(); @@ -671,6 +780,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { ccf::UserId user_id; @@ -717,6 +827,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { auto response_body = nlohmann::json::object(); @@ -759,6 +870,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { ccf::NodeId node_id; diff --git a/src/node/gov/handlers/transactions.h b/src/node/gov/handlers/transactions.h index 5ce76308a68..786b97cfb78 100644 --- a/src/node/gov/handlers/transactions.h +++ b/src/node/gov/handlers/transactions.h @@ -16,6 +16,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { // Extract transaction ID from path parameter @@ -89,6 +90,7 @@ namespace ccf::gov::endpoints switch (api_version) { case ApiVersion::preview_v1: + case ApiVersion::v1: default: { // Lookup committed diff --git a/tests/infra/clients.py b/tests/infra/clients.py index 629cd81f399..76247ef6454 100644 --- a/tests/infra/clients.py +++ b/tests/infra/clients.py @@ -36,8 +36,9 @@ from infra.log_capture import flush_info import ccf.cose -API_VERSION_PREVIEW_01 = "2023-06-01-preview" API_VERSION_CLASSIC = "classic" +API_VERSION_PREVIEW_01 = "2023-06-01-preview" +API_VERSION_01 = "2024-07-01" class OffSettableSecondsSinceEpoch: @@ -1284,7 +1285,10 @@ class APIVersionedCCFClient(CCFClient): def __init__(self, *args, api_version=None, **kwargs): super(APIVersionedCCFClient, self).__init__(*args, **kwargs) self.api_version = api_version - if self.api_version == API_VERSION_PREVIEW_01: + if self.api_version in ( + API_VERSION_PREVIEW_01, + API_VERSION_01, + ): self.client_impl.cose_header_builder = cose_protected_headers_api_v1 else: LOG.error( diff --git a/tests/infra/consortium.py b/tests/infra/consortium.py index e20864086d7..741c39201ec 100644 --- a/tests/infra/consortium.py +++ b/tests/infra/consortium.py @@ -143,6 +143,7 @@ def set_authenticate_session(self, flag): def set_gov_api_version(self, version_s): for cls in ( infra.member.MemberAPI.Preview_v1, + infra.member.MemberAPI.v1, infra.member.MemberAPI.Classic, ): if version_s == cls.API_VERSION: diff --git a/tests/infra/e2e_args.py b/tests/infra/e2e_args.py index 2fa31c4cdc2..25419da330b 100644 --- a/tests/infra/e2e_args.py +++ b/tests/infra/e2e_args.py @@ -424,7 +424,7 @@ def cli_args( "--gov-api-version", help="api-version to be used for accessing /gov endpoints", type=str, - default=infra.clients.API_VERSION_PREVIEW_01, + default=infra.clients.API_VERSION_01, ) add(parser) diff --git a/tests/infra/member.py b/tests/infra/member.py index fd7b1bb3085..d40a8a8b083 100644 --- a/tests/infra/member.py +++ b/tests/infra/member.py @@ -38,9 +38,7 @@ class MemberStatus(Enum): class MemberAPI: - class Preview_v1: - API_VERSION = infra.clients.API_VERSION_PREVIEW_01 - + class v1_Base: def propose(self, member, remote_node, proposal): with remote_node.api_versioned_client( *member.auth(write=True), @@ -133,6 +131,12 @@ def get_recovery_share(self, member, remote_node): raise NoRecoveryShareFound(r) return r.body.json()["encryptedShare"] + class Preview_v1(v1_Base): + API_VERSION = infra.clients.API_VERSION_PREVIEW_01 + + class v1(v1_Base): + API_VERSION = infra.clients.API_VERSION_01 + class Classic: API_VERSION = infra.clients.API_VERSION_CLASSIC diff --git a/tests/js-modules/modules.py b/tests/js-modules/modules.py index 215e437b45a..d838fbf8f19 100644 --- a/tests/js-modules/modules.py +++ b/tests/js-modules/modules.py @@ -12,6 +12,7 @@ import infra.e2e_args import infra.crypto import suite.test_requirements as reqs +import urllib.parse from e2e_logging import test_multi_auth from npm_tests import build_npm_app, deploy_npm_app, test_npm_app, validate_openapi @@ -38,6 +39,41 @@ def test_module_import(network, args): return network +@reqs.description("Test module access") +def test_module_access(network, args): + primary, _ = network.find_nodes() + + bundle_dir = os.path.join(THIS_DIR, "basic-module-import") + bundle = network.consortium.read_bundle_from_dir(bundle_dir) + network.consortium.set_js_app_from_bundle(primary, bundle) + + expected_modules = bundle["modules"] + + with primary.api_versioned_client(api_version=args.gov_api_version) as c: + r = c.get("/gov/service/javascript-modules") + assert r.status_code == http.HTTPStatus.OK, r.status_code + + modules = [e["moduleName"] for e in r.body.json()["value"]] + + assert len(modules) == len(expected_modules) + + for module_def in expected_modules: + raw_name = module_def["name"] + norm_name = f"/{raw_name}" + + assert norm_name in modules, f"{norm_name} not in {modules}" + + r = c.get( + f"/gov/service/javascript-modules/{urllib.parse.quote_plus(norm_name)}" + ) + assert r.status_code == http.HTTPStatus.OK, r + + content = r.body.text() + assert content == module_def["module"] + + return network + + @reqs.description("Test module bytecode caching") @reqs.installed_package("libjs_generic") def test_bytecode_cache(network, args): @@ -424,6 +460,7 @@ def run(args): network = test_js_exception_output(network, args) network = test_module_import(network, args) + network = test_module_access(network, args) network = test_bytecode_cache(network, args) network = test_app_bundle(network, args) network = test_dynamic_endpoints(network, args) diff --git a/tests/schema.py b/tests/schema.py index 56aa95d60fb..0627e7353f6 100644 --- a/tests/schema.py +++ b/tests/schema.py @@ -11,6 +11,7 @@ from packaging import version from infra.runner import ConcurrentRunner import nobuiltins +import packaging.version import e2e_tutorial import e2e_operations @@ -30,10 +31,7 @@ def run(args): documents_valid = True all_methods = [] - def fetch_schema(client, prefix, file_prefix=None): - if file_prefix is None: - file_prefix = prefix - api_response = client.get(f"/{prefix}/api") + def fetch_schema(api_response, target_file_path): check( api_response, error=lambda status, msg: status == http.HTTPStatus.OK.value ) @@ -44,9 +42,7 @@ def fetch_schema(client, prefix, file_prefix=None): fetched_version = response_body["info"]["version"] formatted_schema = json.dumps(response_body, indent=2) - openapi_target_file = os.path.join( - args.schema_dir, f"{file_prefix}_openapi.json" - ) + openapi_target_file = os.path.join(args.schema_dir, target_file_path) try: old_schema.remove(openapi_target_file) @@ -55,15 +51,26 @@ def fetch_schema(client, prefix, file_prefix=None): with open(openapi_target_file, "a+", encoding="utf-8") as f: f.seek(0) - previous = f.read() + previous = f.read().strip() if previous != formatted_schema: file_version = "0.0.0" try: from_file = json.loads(previous) file_version = from_file["info"]["version"] - except (json.JSONDecodeError, KeyError): + file_version = version.parse(file_version) + except ( + json.JSONDecodeError, + KeyError, + packaging.version.InvalidVersion, + ): pass - if version.parse(fetched_version) > version.parse(file_version): + + try: + fetched_version = version.parse(fetched_version) + except packaging.version.InvalidVersion: + pass + + if fetched_version > file_version: LOG.debug( f"Writing schema to {openapi_target_file} - overwriting {file_version} with {fetched_version}" ) @@ -74,9 +81,8 @@ def fetch_schema(client, prefix, file_prefix=None): LOG.error( f"Found differences in {openapi_target_file}, but not overwriting as retrieved version is not newer ({fetched_version} <= {file_version})" ) - alt_file = os.path.join( - args.schema_dir, f"{file_prefix}_{fetched_version}_openapi.json" - ) + prefix, ext = os.path.splitext(openapi_target_file) + alt_file = f"{prefix}_{fetched_version}{ext}" LOG.error(f"Writing to {alt_file} for comparison") with open(alt_file, "w", encoding="utf-8") as f2: f2.write(formatted_schema) @@ -105,19 +111,33 @@ def fetch_schema(client, prefix, file_prefix=None): check = infra.checker.Checker() - with primary.client("user0") as user_client: + with primary.client() as client: LOG.info("user frontend") - if not fetch_schema(user_client, "app"): + if not fetch_schema(client.get("/app/api"), "app_openapi.json"): documents_valid = False - with primary.client() as node_client: LOG.info("node frontend") - if not fetch_schema(node_client, "node"): + if not fetch_schema(client.get("/node/api"), "node_openapi.json"): documents_valid = False - with primary.client("member0") as member_client: LOG.info("member frontend") - if not fetch_schema(member_client, "gov"): + if not fetch_schema(client.get("/gov/api"), "gov_openapi.json"): + documents_valid = False + + with primary.api_versioned_client( + api_version=infra.clients.API_VERSION_PREVIEW_01 + ) as client: + LOG.info("gov API - preview v1") + if not fetch_schema( + client.get("/gov/api"), "gov/2023-06-01-preview/gov.json" + ): + documents_valid = False + + with primary.api_versioned_client( + api_version=infra.clients.API_VERSION_01 + ) as client: + LOG.info("gov API - v1") + if not fetch_schema(client.get("/gov/api"), "gov/2024-07-01/gov.json"): documents_valid = False made_changes = False