Skip to content
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
182 changes: 182 additions & 0 deletions docs/get_delete_api_implementation_guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
# GET & DELETE APIs for Veraison Provisioning Interface
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not needed here. Instead the REST API docs (in the docs repo) should be updated to document the new REST API.

Internal structures generally do not need to be documented -- they are of no intrest to people wanting to use the API, and anyone who wants to know how the API is implemented can (and should) just read the actual code.

Finally, explanations of what has been changed/added as part of this work should be docunted in the commit messages for the commits that make those changes, not in some random file.


## Summary

This implementation adds GET and DELETE functionality to the Veraison Provisioning Interface, allowing users to:
1. **Retrieve endorsements** (reference values and trust anchors) that have been submitted
2. **Delete endorsements** when they are no longer needed

Previously, the interface only supported submitting endorsements via POST.

## Implementation Details

### 1. Protocol Buffer Definitions

Added new message types and RPC methods to `proto/vts.proto`:

- **GetEndorsementsRequest**: Request to retrieve endorsements with optional filtering
- `key_prefix`: Filter by key prefix (optional)
- `endorsement_type`: Type filter ("trust-anchor", "reference-value", or "all")

- **GetEndorsementsResponse**: Response containing matching endorsements
- `endorsements`: List of endorsement entries
- `status`: Operation status

- **DeleteEndorsementsRequest**: Request to delete endorsements
- `key`: Key or key prefix to delete (required)
- `endorsement_type`: Type filter ("trust-anchor", "reference-value", or "all")

- **DeleteEndorsementsResponse**: Response with deletion results
- `deleted_count`: Number of endorsements deleted
- `status`: Operation status

### 2. VTS Service Layer

**File**: `vts/trustedservices/trustedservices_grpc.go`

Implemented two new gRPC methods:

- **GetEndorsements**: Retrieves endorsements from trust anchor and/or reference value stores
- Supports filtering by key prefix
- Supports filtering by endorsement type
- Returns all matching endorsements with their keys and values

- **DeleteEndorsements**: Deletes endorsements from stores
- Supports exact key match or prefix-based deletion
- Supports filtering by endorsement type
- Returns count of deleted entries

### 3. Provisioner Layer

**Files**:
- `provisioning/provisioner/iprovisioner.go`
- `provisioning/provisioner/provisioner.go`

Added two new methods to the provisioner interface and implementation that call the VTS gRPC methods.

### 4. Provisioning API Layer

**Files**:
- `provisioning/api/handler.go`
- `provisioning/api/router.go`

Added two new REST API endpoints:

#### GET /endorsement-provisioning/v1/endorsements

Query parameters:
- `key-prefix` (optional): Filter endorsements by key prefix
- `type` (optional): Filter by type ("all", "trust-anchor", "reference-value"). Default: "all"

Response: JSON with endorsements list

Example:
```bash
curl -H "Accept: application/json" \
"http://localhost:8888/endorsement-provisioning/v1/endorsements?type=trust-anchor"
```

#### DELETE /endorsement-provisioning/v1/endorsements

Query parameters:
- `key` (required): Key or key prefix to delete
- `type` (optional): Filter by type ("all", "trust-anchor", "reference-value"). Default: "all"

Response: JSON with deletion count

Example:
```bash
curl -X DELETE \
"http://localhost:8888/endorsement-provisioning/v1/endorsements?key=my-endorsement-key"
```

### 5. VTS Client Layer

**File**: `vtsclient/vtsclient_grpc.go`

Added wrapper methods in the GRPC client to call the new VTS service methods.

### 6. Tests

**File**: `provisioning/api/handler_test.go`

Added comprehensive unit tests:
- `TestHandler_GetEndorsements_Success`: Test successful retrieval
- `TestHandler_GetEndorsements_WithFilter`: Test with filtering
- `TestHandler_GetEndorsements_InvalidType`: Test invalid type parameter
- `TestHandler_DeleteEndorsements_Success`: Test successful deletion
- `TestHandler_DeleteEndorsements_MissingKey`: Test missing key parameter
- `TestHandler_DeleteEndorsements_Error`: Test error handling

All tests pass successfully.

## API Usage Examples

### Retrieve All Endorsements

```bash
curl -H "Accept: application/json" \
"http://localhost:8888/endorsement-provisioning/v1/endorsements"
```

### Retrieve Trust Anchors Only

```bash
curl -H "Accept: application/json" \
"http://localhost:8888/endorsement-provisioning/v1/endorsements?type=trust-anchor"
```

### Retrieve Endorsements with Key Prefix

```bash
curl -H "Accept: application/json" \
"http://localhost:8888/endorsement-provisioning/v1/endorsements?key-prefix=arm-cca"
```

### Delete Specific Endorsement

```bash
curl -X DELETE \
"http://localhost:8888/endorsement-provisioning/v1/endorsements?key=my-key"
```

### Delete All Trust Anchors with Prefix

```bash
curl -X DELETE \
"http://localhost:8888/endorsement-provisioning/v1/endorsements?key=prefix-&type=trust-anchor"
```

## Security Considerations

- All new endpoints are protected by the same authorization middleware as the existing submit endpoint
- Users must have the `ProvisionerRole` to access these endpoints
- Deletion is permanent and cannot be undone
- Key prefix matching allows batch deletion - use with caution

## Files Modified

1. `proto/vts.proto` - Proto definitions
2. `proto/vts_grpc.pb.go` - Generated gRPC code (manually updated)
3. `proto/endorsement_query.go` - New proto message structures
4. `vts/trustedservices/trustedservices_grpc.go` - VTS service implementation
5. `provisioning/provisioner/iprovisioner.go` - Provisioner interface
6. `provisioning/provisioner/provisioner.go` - Provisioner implementation
7. `provisioning/api/handler.go` - API handlers
8. `provisioning/api/router.go` - Route registration
9. `provisioning/api/handler_test.go` - Unit tests
10. `provisioning/api/mocks/iprovisioner.go` - Mock updates
11. `vtsclient/vtsclient_grpc.go` - VTS client wrapper

## Testing

All unit tests pass:
```bash
cd provisioning/api && go test -v
```

Build verification:
```bash
go build ./provisioning/...
go build ./vts/...
```
37 changes: 37 additions & 0 deletions proto/endorsement_query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2025 Contributors to the Veraison project.
// SPDX-License-Identifier: Apache-2.0
package proto

// GetEndorsementsRequest is the request message for GetEndorsements RPC
type GetEndorsementsRequest struct {
// Optional key prefix to filter endorsements. If empty, returns all endorsements.
KeyPrefix string `json:"key_prefix,omitempty"`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The notion of a "key" should not be exposed in the REST API. The user of the API is not expected to know that endorsements are stored in a key-value store, let alone what the format of keys is (that is a purely internal implementation detail, and is liable to change at any time).

Instead parameters for narrowing down the results should refer to conceptual attributes of the endorsements, e.g. the attestation scheme.

// Type of endorsement to retrieve: "trust-anchor", "reference-value", or "all"
EndorsementType string `json:"endorsement_type,omitempty"`
}

// EndorsementEntry represents a single endorsement entry
type EndorsementEntry struct {
Key string `json:"key"`
Values []string `json:"values"`
}

// GetEndorsementsResponse is the response message for GetEndorsements RPC
type GetEndorsementsResponse struct {
Endorsements []*EndorsementEntry `json:"endorsements"`
Status *Status `json:"status"`
}

// DeleteEndorsementsRequest is the request message for DeleteEndorsements RPC
type DeleteEndorsementsRequest struct {
// Key or key prefix to delete
Key string `json:"key"`
// Type of endorsement to delete: "trust-anchor", "reference-value", or "all"
EndorsementType string `json:"endorsement_type,omitempty"`
}

// DeleteEndorsementsResponse is the response message for DeleteEndorsements RPC
type DeleteEndorsementsResponse struct {
DeletedCount int32 `json:"deleted_count"`
Status *Status `json:"status"`
}
35 changes: 35 additions & 0 deletions proto/vts.proto
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,35 @@ message PublicKey {
string key = 1;
}

message GetEndorsementsRequest {
// Optional key prefix to filter endorsements. If empty, returns all endorsements.
string key_prefix = 1;
// Type of endorsement to retrieve: "trust-anchor", "reference-value", or "all"
string endorsement_type = 2;
}

message EndorsementEntry {
string key = 1;
repeated string values = 2;
}

message GetEndorsementsResponse {
repeated EndorsementEntry endorsements = 1;
Status status = 2;
}

message DeleteEndorsementsRequest {
// Key or key prefix to delete
string key = 1;
// Type of endorsement to delete: "trust-anchor", "reference-value", or "all"
string endorsement_type = 2;
}

message DeleteEndorsementsResponse {
int32 deleted_count = 1;
Status status = 2;
}

// Client interface for the Veraison Trusted Services component.
// protolint:disable MAX_LINE_LENGTH
service VTS {
Expand All @@ -49,6 +78,12 @@ service VTS {
rpc GetSupportedProvisioningMediaTypes(google.protobuf.Empty) returns (MediaTypeList);
rpc SubmitEndorsements(SubmitEndorsementsRequest) returns (SubmitEndorsementsResponse);

// Returns endorsements (trust anchors and/or reference values) based on the provided filter
rpc GetEndorsements(GetEndorsementsRequest) returns (GetEndorsementsResponse);

// Deletes endorsements (trust anchors and/or reference values) based on the provided key
rpc DeleteEndorsements(DeleteEndorsementsRequest) returns (DeleteEndorsementsResponse);

// Returns the public key used to sign evidence.
rpc GetEARSigningPublicKey(google.protobuf.Empty) returns (PublicKey);
}
Expand Down
77 changes: 77 additions & 0 deletions proto/vts_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading