Skip to content

ManagedCCF: Resolving mismatches with existing API specification #27826

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import "@typespec/rest";
import "@typespec/versioning";
import "@azure-tools/typespec-azure-core";
import "@azure-tools/typespec-client-generator-core";

import "./common.tsp";
import "./cose.tsp";
Expand All @@ -12,13 +13,15 @@ namespace Microsoft.ManagedCcf.Acks;
@TypeSpec.Rest.resource("state-digests")
model StateDigest {
@doc("Identifier for member this stateDigest applies to.")
@visibility("query")
@visibility("read", "query")
@key
memberId: memberId;

#suppress "@azure-tools/typespec-azure-core/property-name-conflict" "Linter is not aware of ClientGenerator library"
@doc("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}$")
digest: string;
@Azure.ClientGenerator.Core.clientName("digest", "csharp")
stateDigest: string;
}

interface StateDigests {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@
"key9497": "NiNrjmA9/aSj4F076mVdrA=="
},
"uvmEndorsements": {
"key9553": "cbneXARxfLGcqw3cc09mYQ=="
"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"
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
},
"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"
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"responses": {
"200": {
"body": {
"digest": "1cdc59855bb6b7edee42769ca3767bc9684b7a62ffcfcb8751a75dbe71c28e49"
"memberId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970",
"stateDigest": "1cdc59855bb6b7edee42769ca3767bc9684b7a62ffcfcb8751a75dbe71c28e49"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"responses": {
"200": {
"body": {
"digest": "1cdc59855bb6b7edee42769ca3767bc9684b7a62ffcfcb8751a75dbe71c28e49"
"memberId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970",
"stateDigest": "1cdc59855bb6b7edee42769ca3767bc9684b7a62ffcfcb8751a75dbe71c28e49"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ model Member {

@doc("x509 certificate used as this member's identity.")
certificate: pem;

@doc("x509 key used to encrypt this member's key shares, if they are a recovery member.")
publicEncryptionKey?: pem;
}

/// Node types
Expand Down Expand Up @@ -216,17 +219,24 @@ model JoinPolicy {
measurements: bytes[];
}

@doc("Collection of claims regarding a specific feed.")
model FeedInfo {
@doc("Security version number claimed by this endorser.")
svn: string;
}

@doc("Collection of endorsement feeds, keyed by feed name.")
model UvmEndorsementFeeds extends Record<FeedInfo> {}

@doc("Join policy fields specific to nodes running on AMD SEV-SNP hardware.")
model SnpJoinPolicy {
...JoinPolicy;

// TODO: Work out what the actual types of these are

@doc("Collection of acceptable host data values.")
hostData: Record<bytes>;

@doc("Collection of acceptable UVM endorsements.")
uvmEndorsements: Record<bytes>;
@doc("Collection of acceptable UVM endorsements. Keyed by endorser's did.")
uvmEndorsements: Record<UvmEndorsementFeeds>;
}

@TypeSpec.Rest.resource("service")
Expand Down Expand Up @@ -271,6 +281,15 @@ model JwtIssuer {
caCertBundleName?: string;
}

@doc("Describes a single JWK.")
model Jwk {
@doc("x509 cert used to validate claims made by this key.")
certificate: pem;

@doc("Issuer ID of entity who issued this key.")
issuer?: string;
}

@doc("Chain of endorsed certificates (PEM format) leading to a CA.")
scalar caCertBundle extends string;

Expand All @@ -287,6 +306,9 @@ model JwkInfo {

@doc("Collection of CAs used to authenticate connections with issuers. Keyed by governance-controlled bundle names.")
caCertBundles: Record<caCertBundle>;

@doc("Collection of retrieved JWKs. Keyed by kid.")
keys: Record<Jwk>;
}

/// Service info types
Expand Down Expand Up @@ -328,7 +350,7 @@ model ServiceInfo {
creationTransactionId: transactionId;

@doc("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.")
previousServiceCreationTransactionId?: pem;
previousServiceCreationTransactionId?: transactionId;

#suppress "@azure-tools/typespec-azure-core/no-unknown" "This is arbitrary JSON"
@doc("Arbitrary service-defined metadata about this service. May be used by constitution or application code, but will not affect any core framework decisions.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@
"key9497": "NiNrjmA9/aSj4F076mVdrA=="
},
"uvmEndorsements": {
"key9553": "cbneXARxfLGcqw3cc09mYQ=="
"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"
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
},
"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"
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"responses": {
"200": {
"body": {
"digest": "1cdc59855bb6b7edee42769ca3767bc9684b7a62ffcfcb8751a75dbe71c28e49"
"memberId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970",
"stateDigest": "1cdc59855bb6b7edee42769ca3767bc9684b7a62ffcfcb8751a75dbe71c28e49"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"responses": {
"200": {
"body": {
"digest": "1cdc59855bb6b7edee42769ca3767bc9684b7a62ffcfcb8751a75dbe71c28e49"
"memberId": "f8ac7c60c164f7f13c04ba41645b18eabcc55a8f799c83a90d001f4e89907970",
"stateDigest": "1cdc59855bb6b7edee42769ca3767bc9684b7a62ffcfcb8751a75dbe71c28e49"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down Expand Up @@ -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.",
Expand Down Expand Up @@ -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.",
Expand All @@ -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": {
Expand Down Expand Up @@ -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": [
Expand Down Expand Up @@ -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": {
Expand Down Expand Up @@ -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"
}
}
},
Expand Down Expand Up @@ -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."
Expand Down