Skip to content
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

[BACK-2165] [BACK-2164] [BACK-2163] Add app attestation and assertion api documentation. #58

Open
wants to merge 9 commits into
base: master
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
dist
build
.idea/
.DS_Store
114 changes: 114 additions & 0 deletions reference/auth.v1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ tags:
description: >-
List and manage users.

- name: Attestation
description: >-
Attest and assert an app is a valid instance of an iOS app.

paths:
'/auth/login':
post:
Expand Down Expand Up @@ -719,6 +723,98 @@ paths:
security:
- serverToken: []

'/v1/attestations/challenges':
post:
operationId: CreateAttestationChallenge
summary: Create an attestation challenge.
description: >-
Starts the attestation flow by requesting an attestation challenge that the client will later use in an Apple API call and to verify an attestation.
requestBody:
content:
'application/json':
schema:
$ref: './auth/models/newappchallenge.v1.yaml'
responses:
'201':
$ref: '#/components/responses/AppChallenge'
'400':
$ref: './common/responses/badrequest.v1.yaml'
'401':
$ref: './common/responses/unauthorized.v1.yaml'
'403':
$ref: './common/responses/forbidden.v1.yaml'
tags:
- Attestation

'/v1/attestations/verifications':
post:
operationId: VerifyAttestation
summary: Verify an attestation.
description: >-
This confirms the app is a valid instance of an iOS app. It must use the previously generated challenge.
requestBody:
content:
'application/json':
schema:
$ref: './auth/models/attestationverify.v1.yaml'
responses:
'204':
description: The attestation was verified successfully.
'400':
$ref: './common/responses/badrequest.v1.yaml'
'401':
$ref: './common/responses/unauthorized.v1.yaml'
'403':
$ref: './common/responses/forbidden.v1.yaml'
tags:
- Attestation

'/v1/assertions/challenges':
post:
operationId: CreateAssertionChallenge
summary: Create an assertion challenge.
description: >-
Requests an assertion challenge be generated. This can only happen after attestation has been verified.
requestBody:
content:
'application/json':
schema:
$ref: './auth/models/newappchallenge.v1.yaml'
responses:
'201':
$ref: '#/components/responses/AppChallenge'
'400':
$ref: './common/responses/badrequest.v1.yaml'
'401':
$ref: './common/responses/unauthorized.v1.yaml'
'403':
$ref: './common/responses/forbidden.v1.yaml'
tags:
- Attestation

'/v1/assertions/verifications':
post:
operationId: VerifyAssertion
summary: Verify an assertion.
description: >-
This verifies an assertion and returns X.509 certficates.
requestBody:
content:
'application/json':
schema:
$ref: './auth/models/assertionverify.v1.yaml'
responses:
'200':
$ref: '#/components/responses/Assertion'
'400':
$ref: './common/responses/badrequest.v1.yaml'
'401':
$ref: './common/responses/unauthorized.v1.yaml'
'403':
$ref: './common/responses/forbidden.v1.yaml'
tags:
- Attestation

components:
securitySchemes:
basicAuth:
Expand Down Expand Up @@ -998,3 +1094,21 @@ components:
required:
- code
- reason
AppChallenge:
description: 'Challenge generated by server and which client should use in later operations.'
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider a re-wording?

Suggested change
description: 'Challenge generated by server and which client should use in later operations.'
description: A server-generated challenge proving a client application's identity to Tidepool.

headers:
'X-Tidepool-Session-Token':
$ref: './common/headers/tidepoolsessiontoken.v1.yaml'
content:
'application/json':
schema:
$ref: './auth/models/appchallenge.v1.yaml'
Assertion:
description: 'Certificates returned upon successful assertion.'
headers:
'X-Tidepool-Session-Token':
$ref: './common/headers/tidepoolsessiontoken.v1.yaml'
content:
'application/json':
schema:
$ref: './auth/models/assertionsecret.v1.yaml'
7 changes: 7 additions & 0 deletions reference/auth/models/appchallenge.v1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
title: Challenge
description: Challenge generated by server.
type: object
properties:
challenge:
type: string
minLength: 1
8 changes: 8 additions & 0 deletions reference/auth/models/assertionsecret.v1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
title: Assertion Secret
description: Data sent back upon successful app assertion.
type: object
properties:
data:
oneOf:
- $ref: './coastalresponse.v1.yaml'
- $ref: './palmtreeresponse.v1.yaml'
34 changes: 34 additions & 0 deletions reference/auth/models/assertionverify.v1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
title: Assertion Verify
description: Request body for verifying an assertion.
type: object
properties:
assertion:
type: string
pattern: '^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$'
description: Base64 encoded data received from Apple App Attest API. User must base64 encode the binary data received from Apple.
clientData:
type: object
properties:
challenge:
description: The previously returned assertion challenge.
Copy link
Contributor

Choose a reason for hiding this comment

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

This is what a client receives after posting to /v1/(assertions|attestations)/challenges right?

The body of that call is a JSON object, but this property is defined as a string, so probably that means it's base64 encoded? If so, that should be called out here.

Or does the endpoint expect the original JSON object supplied, in which case this isn't a strong really at all, but rather an object as defined in ./auth/models/appchallenge.v1.yaml.

Or if it's a string, but not base64 encoded, well, that'd be bad, it should be base64 encoded, else you run into a lot of quote-escaping issues and things get really ugly.

type: string
minLength: 1
partner:
description: Code name of partner to retrieve certificate from.
type: string
minLength: 1
Copy link
Contributor

Choose a reason for hiding this comment

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

If this is an enum, then minLength is not necessary, and can only confuse things, right? I suggest removing this.

Suggested change
minLength: 1

enum:
lostlevels marked this conversation as resolved.
Show resolved Hide resolved
- Coastal
- PalmTree
partnerData:
lostlevels marked this conversation as resolved.
Show resolved Hide resolved
oneOf:
- $ref: './coastalrequest.v1.yaml'
- $ref: './palmtreerequest.v1.yaml'
description: Actual data requested by client. Must include the previously requested challenge.
keyId:
$ref: './keyid.v1.yaml'
description: Base64 encoded key Id received from Apple App Attest API.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
description: Base64 encoded key Id received from Apple App Attest API.

This property will be dropped, as you used a $ref as a sibling. So the description field in the keyId.v1.yaml file will be used instead.

required:
- attestation
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
- attestation
- assertion

Based on the filename and line 5 of this file, I assume this was a typo?

- clientData
- keyId
18 changes: 18 additions & 0 deletions reference/auth/models/attestationverify.v1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
title: Attestation Verify
description: Request body for verifying an attestation.
type: object
properties:
attestation:
type: string
pattern: '^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$'
description: Base64 encoded data received from Apple App Attest API. User must base64 encode the binary data received from Apple.
lostlevels marked this conversation as resolved.
Show resolved Hide resolved
challenge:
type: string
Copy link
Contributor

Choose a reason for hiding this comment

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

See my comment on the challenge field of assertionverify.v1.yaml.

minLength: 1
description: The previously returned attestation challenge.
keyId:
$ref: './keyid.v1.yaml'
required:
- attestation
- challenge
- keyId
26 changes: 26 additions & 0 deletions reference/auth/models/coastalrequest.v1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
title: Coastal Request Data
description: Data to send to Coastal's API.
Copy link
Contributor

Choose a reason for hiding this comment

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

This could be improved with details. Which Coastal API? For what purpose? To what end?

If the API is published anywhere publicly, it might be nice to link to it.

type: object
properties:
rcInstanceId:
type: string
minLength: 1
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably better than "minLength: 1" is to say

required:
  - rcInstanceId

rcHWVersions:
type: array
items:
type: string
rcSWVersions:
type: array
items:
type: string
phdTypeId:
type: string
minLength: 1
phdInstanceId:
type: string
minLength: 1
csr:
type: string
pattern: '^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$'
description: Base64 encoded string of the PEM formatted certificate signing request to the partner API.
minLength: 1
21 changes: 21 additions & 0 deletions reference/auth/models/coastalresponse.v1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
title: Coastal Response
description: Data retrieved from Coastal's API.
Copy link
Contributor

Choose a reason for hiding this comment

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

This too could be improved with details. Which Coastal API? For what purpose? To what end?

type: object
properties:
certificates:
description: X.509 certificates to be used for client authentication.
type: array
items:
type: object
properties:
content:
type: string
pattern: '^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$'
description: base64 encoded X.509 certificate in DER format.
ttlInDays:
type: integer
type:
type: string
enum:
- CONSTRAINED
- WILDCARD
4 changes: 4 additions & 0 deletions reference/auth/models/keyid.v1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
title: Key Id
description: Base64 encoded key identifier received from apple. The Key Id is some shortened data, usually a hash, used to identify the longer actual key.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit

Suggested change
description: Base64 encoded key identifier received from apple. The Key Id is some shortened data, usually a hash, used to identify the longer actual key.
description: An opaque identifier received from Apple.

As it's used here "opaque" is understood to indicate that whatever data we receive, we shouldn't try to decode it or understand it or anything. This is commonly done because its creator is reserving the right to change its structure or meaning at any time.

type: string
pattern: '^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$'
10 changes: 10 additions & 0 deletions reference/auth/models/newappchallenge.v1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
title: New App Challenge
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I wouldn't bother putting "new" in the filename or title... It isn't important, and can only confuse people (was there an older one?)

description: Information needed when generating an attestation or assertion challenge.
type: object
properties:
keyId:
type: string
pattern: '^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$'
description: Base64 encoded key Id received from Apple App Attest API.
Comment on lines +5 to +8
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
keyId:
type: string
pattern: '^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$'
description: Base64 encoded key Id received from Apple App Attest API.
keyId:
$ref: './keyid.v1.yaml'

required:
- keyId
8 changes: 8 additions & 0 deletions reference/auth/models/palmtreerequest.v1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
title: Palm Tree Request Data
description: Data to send to Palm Tree's API.
type: object
properties:
csr:
description: Base64 encoded certificate signing request.
Copy link
Contributor

Choose a reason for hiding this comment

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

If the details matter... The Coastal request data indicates that it is "base64 encoded DER certificates".

Here, it says only "Base64 encoded"... Is it like Coastal, in that it's base64 DER, or rather, is it PEM (which is also base64 encoded, but with a slightly alternative structure).

Not a big deal to call it out, but you could save someone a bit of head scratching.

type: string
pattern: '^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$'
24 changes: 24 additions & 0 deletions reference/auth/models/palmtreeresponse.v1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
title: Palm Tree Response
description: Data retrieved from Palm Tree's API.
type: object
properties:
type:
type: string
enrollment:
type: object
properties:
body:
type: string
description: PEM encoded certificate.
Copy link
Contributor

Choose a reason for hiding this comment

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

In another comment, I mentioned a difference between "base64 encoded", "base64 encoded DER" and now it gets even weirder as we add "PEM" to mix.

So I urge you be consistent and exact in these terms to save people headaches later.

id:
type: string
issuerName:
type: string
serialNumber:
type: string
subjectName:
type: string
status:
type: string
validityPeriod:
type: string
4 changes: 4 additions & 0 deletions reference/common/models/base64.v1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
title: Base64
type: string
Copy link
Member

Choose a reason for hiding this comment

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

We could use the format value to indicate base64 encoding of the string type: https://swagger.io/docs/specification/data-models/data-types/ - but I like the explicit pattern

Copy link
Contributor

Choose a reason for hiding this comment

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

We could use the format value to indicate base64 encoding of the string type: https://swagger.io/docs/specification/data-models/data-types/ - but I like the explicit pattern

I'm not against the explicit pattern at all, but I would like to see a $ref to his used in more places, so that I don't have to squint at the regexp in so many different places and try to double-check that there wasn't a cut and paste error made. :)

description: Base64 encoded data.
pattern: '^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$'
Loading