FHIR Chat · Sharing auth tokens · Security and Privacy

Stream: Security and Privacy

Topic: Sharing auth tokens


view this post on Zulip Lloyd McKenzie (Dec 03 2021 at 23:59):

In DaVinci DTR we have a situation where a SMART app launched by an EHR is going to store patient identifiable and potentially sensitive information on a payer (because there's no ability as yet for the EHRs to store the information). However, to protect against a compromised app from having access to the payer-stored information for all patients, we want the payer to be able to enforce that the SMART app only has access to information related to the same patient on the payer as it has access to on the EHR. I.e. the app will be limited both in the time it has access and the patient has access to (which is the same mechanism used by EHRs to protect against compromised apps).

To achieve this, the proposal is for the SMART app to pass the EHR's access token to the payer when requesting access. The payer would then validate the token by attempting to query the Patient record based on the URL present in either the search URL or in the POSTed DocumentReference. If the read was a success, that would mean that the application would have access to the data associated with that patient URL (and only that patient URL).

In practice, this would also mean that the payer would be able to issue other queries against the EHR posing as the DTR SMART App. We consider this to be a low risk:

  • The payer is a covered party and would face serious consequences for misusing the token
  • The EHR can (and would) log IPS addresses of TLS connections and thus there would be some degree of capability to trace back to a payer system
  • The DTR app has the ability to query all of the information anyhow and embed the information in a QuestionnaireResponse that might be stored on the payer's server anyhow

Are there other risks we should consider/be worried about?

view this post on Zulip Josh Mandel (Dec 04 2021 at 01:34):

What is the relationship between the app and the payer? Certainly an app should not be sharing access tokens with an external system, but if the app is managed by the payer, it's not passing a token anywhere, just using the token it received from the EHR.

view this post on Zulip Josh Mandel (Dec 04 2021 at 01:39):

In any case, a relying party should not make extra queries to test out the token when it can use token introspection for this purpose.

view this post on Zulip Josh Mandel (Dec 04 2021 at 01:40):

(It would be pretty neat if we had a variation of token introspection where the result is cryptographically signed with an issuance time, so it can be passed along safely as proof of the access you had.)

view this post on Zulip Lloyd McKenzie (Dec 04 2021 at 03:19):

Apps will be registered with both the EHR and the payer. However, apps will be shared across payers - and EHRs will have the choice of which app(s) they choose to use. That app will be used for all payers.

view this post on Zulip Lloyd McKenzie (Dec 04 2021 at 03:20):

Token introspection would allow confirmation that the EHR had issued it (and it hadn't been manufactured by the app)?

view this post on Zulip Paul Church (Dec 04 2021 at 04:19):

Passing bearer tokens around is never great, it just adds one more place to attack that can have sensitive secrets inside. The payer system certainly should not persist or log the token under any circumstances.

This does sound like a case for token introspection - it's much more suitable than making a call to the resource server for a resource you don't actually want. The payer is asking the EHR auth server for the properties of the token the payer is holding, which will include the patient.

Josh's additional idea is really interesting - what you really want is for the app to pass a different kind of signed proof token to the payer. But that would be breaking entirely new ground. Just thinking out loud, is there any way for the app to ask the EHR auth server for some kind of downscoped auth token so the risk of handing it over to the payer is less?

view this post on Zulip Josh Mandel (Dec 04 2021 at 04:27):

Good point -- We've talked about using https://datatracker.ietf.org/doc/html/rfc8693 in SMART (but we'd still require some careful profiling to request a downscoped access token they preserves full contextual metadata like patient id and encounter id but conveys no API access; plus we'd still want something like regular SMARTv2 introspection or to tell what the patient is).

view this post on Zulip Lloyd McKenzie (Dec 04 2021 at 05:20):

Just to confirm, the token itself would be cryptographically verifiable by a client as having been signed by the EHR. Certainly passing a more restricted one that still conveyed the necessary metadata would meet our use-case if that was possible.

view this post on Zulip Lloyd McKenzie (Dec 04 2021 at 05:21):

Agree that prohibiting persistence or logging would be appropriate. The log could store the introspected metadata, but not the token itself.

view this post on Zulip John Moehrke (Dec 04 2021 at 14:38):

Do you have this drawn up in an interaction diagram? I am getting lost on the "actors" involved, as you are using terms like payor, and app, and EHR. Where at the payor there is the OAuth authorization actor, and the resource-server. I think you are describing conversation with the payer authorization service. I think you are describing how that payer authorization service would confirm that the context of an access token request is legitimate? It is not uncommon for a request for an access token to have context used in addition to the request parameters (scope, etc). I would expect that the payer authorization service would need to introspect, and understand the introspected format (i.e. SMART token format).

view this post on Zulip Lloyd McKenzie (Dec 04 2021 at 15:09):

The payer doesn't have an OAuth authorization actor, necessarily. The app is simply making a 'create', 'update' or 'search' request against a DocumentReference endpoint and passing a token in the header. The intent is that the service at that endpoint would introspect the token and determine authorization itself. If it chooses to delegate that responsibility to an authorization service, I suppose it could, but given that this will be a semi-custom workflow, I'm not sure that the complexity would be worth it.

view this post on Zulip John Moehrke (Dec 04 2021 at 15:13):

so where does it get that token from? In SMART each resource-service endpoint has an OAuth authorization service endpoint

view this post on Zulip Josh Mandel (Dec 04 2021 at 17:55):

token itself would be cryptographically verifiable by a client as having been signed by the EHR.

SMART does not define any access token format; you should be looking at token introspection if you need to evaluate whether a token is valid and what it's good for.

view this post on Zulip Josh Mandel (Dec 04 2021 at 17:56):

Jumping all the way back to the top of this discssion: I assuming you're already using OpenID Connect and getting an id_token from the EHR to represent the user, and already limiting access to any payer-backed storage based on this (so an app can only access data that a given user is allowed to see)?

view this post on Zulip Josh Mandel (Dec 04 2021 at 18:01):

It's important to understand where and how you expect all this new machinery to work. New profiles are easy to write for all of this, but getting agreement and implementation from real-world sytems takes buy-in, and this kind of "net new" protocol work should be happening in a framework-level IG so it's reusable, not tucked away in a use-case-specific IG.

view this post on Zulip Josh Mandel (Dec 04 2021 at 18:04):

However, apps will be shared across payers - and EHRs will have the choice of which app(s) they choose to use.

These apps should not be passing bearer tokens around to payers, then. If payers don't trust the app to mediate the EHR connection, they should establish their own EHR connection or we should introduce new explicit delegation machinery.

view this post on Zulip Lloyd McKenzie (Dec 05 2021 at 03:48):

App authenticates to the EHR using OpenID and OAuth. App authenticates to the payer using TLS and a shared secret. No user-based OAuth. The intention is to pass the EHR's auth token to the payer to determine what access the payer should provide.

view this post on Zulip Lloyd McKenzie (Dec 05 2021 at 03:49):

The payer doesn't need a connection to the EHR. The payer just wants to ensure that the app is limited to reading and writing the same patient on their system that they can read from the EHR. (The only thing they can read or write on the payer is stored "work in progress" previously saved by the app.)

view this post on Zulip John Moehrke (Dec 05 2021 at 12:44):

so in trying to be more simple, you have setup the condition that you are trying to resolve now. In the simple world you describe, there is a SMART protected world between the App and the EHR, and a blanket trust (TLS and secret?) between the App and the Payor that presumes the App will not do anything wrong. But now you are asking about a case where the Payor is not trusted that far.

What I was suggesting is if the Payor has a OAuth authorization service protecting the Payor; then when the App requests a Payor access token the Payor's Authorization Service decision is based on the security context with the App. This security context can be based on many things. For example in the App->EHR it can be based on an Open-ID-Connect token. So in your case the Payors Authorization Service can require the App to get an access token from the EHR OAuth Authorization Service with the audience of the Payors Authorization Service. This Token would have be profiled to hold the important EHR context. Likely introspection would be needed by the Payor Authorization Service to the EHR Authorization Service. There clearly is a trust relationship between the Payor OAuth Authorization Service and the EHR OAuth Authorization Service.

Given that your initial conditions are blanket trust between App and Payor; then just continue this and trust that the App won't do anything wrong. If you can't hold to this, then you can't trust the App this way at all. So your blanket trust either survives, or is totally discarded.

I fear that there is some expectation that the App->EHR token can be passed in the App->Payor. This would possibly work, but would (a) require the token is issued with an audience that includes the Payor, and (b) there is a trust (introspection) between the Payor resource service and the EHR OAuth authorization service. Essentially the OAuth Authorization Service of the EHR also covers the Payor.

view this post on Zulip Josh Mandel (Dec 05 2021 at 16:53):

Agree with John -- your assumptions aren't holding up here. Best to step back and re-evaluate what you're trying to accomplish.

view this post on Zulip Lloyd McKenzie (Dec 05 2021 at 17:17):

  1. The EHR and payer aren't going to use the same auth server. (If the payer has an auth server at all)
  2. We don't want the user to have to authenticate twice when launching the SMART app
  3. We can't trust the app to ask the payer for access to the same patient that it was granted access to on the EHR. That's the threat we're trying to mitigate.
    The payer has some trust in the app, in that it's been certified for use. However, the payer doesn't have control over the code. If a malicious change is made to the app, it might start to do things it's not supposed to do. This is similar to the trust relationship between EHRs and apps. This 'partial trust' situation is mitigated by SMART's limited scope access tokens such that an app can't access beans unless a user asks it to and then can only access the specific patient (and scopes) that the user gives permission to. So the damage it can do is limited. We're trying to accomplish the same thing on the payer side - without requiring separate user authentication on the payer side.

view this post on Zulip Josh Mandel (Dec 05 2021 at 17:33):

Keep in mind that for these scenarios user authentication and authorization generally do not involve any actual clicks or choices; so the idea of "authenticate twice" is a misleading characterization (two times zero clicks is still zero clicks).

In any case, I'd strongly recommend you avoid adding requirements in an IG specific fashion. And strongly recommend against sharing access tokens in the way you've suggested.

view this post on Zulip Lloyd McKenzie (Dec 05 2021 at 18:26):

More specifically - the payer will have no clue who the user is and will not have a relationship with the auth server of the EHR that could reasonably validate the user identity. The payer doesn't need to know the user. It only needs to know what patient the EHR has authorized the app to access.

So, given the lack of a shared auth server between payer and EHR, lack of any expectation that payer and EHR can talk to each other except with the untrusted app as an intermediary, and the lack of trust in the app to only ask the payer for data related to the current patient, how would you advise conveying the "patient context" restriction from the EHR to the payer if we don't share an auth token granted to the app? (We could certainly have the app solicit a second auth token with no privileges that it could pass to the payer if this could be introspected to determine the patient and validated as having come from the EHR.)

view this post on Zulip Vassil Peytchev (Dec 05 2021 at 18:42):

How does the payer know that the patient in the EHR corresponds to a patient/member in the payer system?

view this post on Zulip Lloyd McKenzie (Dec 05 2021 at 20:28):

The record created on the Payer's system will include the EHR's patient URL in Reference.reference and the payer's member id (which the app will already have determined) in member.identifier. Queries by the app will be based solely on Reference.reference. The member identifier is only for the use of the app.

view this post on Zulip Brian Postlethwaite (Dec 06 2021 at 04:03):

If the EHR isn't storing the additional data, then you have another resource location, and I guess what we're now talking about is what is the authentication mechanism on that resource server (storage)?
That's what we've used https://datatracker.ietf.org/doc/html/rfc8693 for on 2 of our projects quite successfully.

view this post on Zulip Lloyd McKenzie (Dec 06 2021 at 04:08):

Right. The authentication mechanism from the app to the EHR is not user-specific. We want to make it patient-specific. And we want the selection of the patient to be completely controlled by the EHR, not the app.

view this post on Zulip Lloyd McKenzie (Dec 06 2021 at 04:15):

My challenge is that we can't get the EHR (or the EHR's auth server) to do anything different. (This whole "let's store stuff on the payer" is a work-around kludge that we plan to use for the 2-3 years it takes the EHRs to have the ability to handle storing the relevant information themselves.) So something that requires revision of EHR authorization functionality won't fly.

view this post on Zulip Grahame Grieve (Dec 06 2021 at 04:33):

it sounds to me like you want a JWT that grants access that's different to the OAuth token, and specific to this use

view this post on Zulip Josh Mandel (Dec 06 2021 at 04:33):

I'd suggest using existing available capabilities to mitigate threats.

For example, a Payer can host an API where the application provides an id_token (signed by the EHR during SMART launch) as evidence of a recent launch, plus (perhaps if you really need it) a patient ID (simply asserted by the app), and ensure that no more than one patient per launch can be addressed.

Keep in mind that apps might not actually scope their launches to a single patient though -- like, a "dashboard of active cases" for a clinical administrator or whatever wouldn't even fit this model, and I don't see why you'd rule it out.

view this post on Zulip Grahame Grieve (Dec 06 2021 at 04:33):

patient ID + granted rights

view this post on Zulip Josh Mandel (Dec 06 2021 at 04:36):

it sounds to me like you want a JWT that grants access that's different to the OAuth token, and specific to this use

This is what we were discussing above (signed introspection respond and/or token exchange would be technologies to accomplish this).

view this post on Zulip Vassil Peytchev (Dec 06 2021 at 04:38):

As described, the connection between the patient on the EHR server, and the reference to the patient on the payer server is at the FHIR layer, so looking at other layers to validate that link is unlikely to work.

It seems to me that the essence of what is asked for is to have the Patient.id that is used in querying the payer server, together with an expiration date, to be signed by the EHR.

With a few extensions, the following might work (as crude and inelegant as it may be):

  1. App authenticates with EHR, for scope of patient P.
  2. App uses a special operation on the EHR with parameter the Patient.id that returns a Consent resource (with subject the full url of the patient resource, and expiration timestamp a few minutes in the future), and a Provenance resource with target the Consent resource and a signature that is trusted by the payer server.
  3. All queries on the patient server have to become operations, that will contain the Consent and Provenance resources as a parameter.

view this post on Zulip Lloyd McKenzie (Dec 06 2021 at 04:38):

The app will have access to the payer. I don't really need access. I want to restrict access to the payer. I want the controller of that restriction to be the EHR. But can't require anything of the EHR that it doesn't do today.

view this post on Zulip Lloyd McKenzie (Dec 06 2021 at 04:39):

@Vassil Peytchev I don't expect the link to validate. This isn't going to be a proper payer FHIR server. This is a single-purpose FHIR interface dumping ground for EHR data. If the payer actually exposes data over a FHIR interface (most don't), it would have a different base URL from this.

view this post on Zulip Lloyd McKenzie (Dec 06 2021 at 04:40):

#2 fails - as it requires the EHR to implement a new operation. That's not really an option for us. Whatever we do has to work with the functionality that EHRs have today.

view this post on Zulip Vassil Peytchev (Dec 06 2021 at 04:45):

I was referring to this when talking about "validating the reference":

The record created on the Payer's system will include the EHR's patient URL in Reference.reference

But in general, yes, I expect that what is being asked is likely to require something different from the EHR...

view this post on Zulip Lloyd McKenzie (Dec 06 2021 at 04:48):

We want it to be exactly what's on the EHR. It's not for the payer's use, it's for the app's use.

view this post on Zulip Lloyd McKenzie (Dec 06 2021 at 04:49):

I.e. the full URL from the EHR. (Having a DocumentReference on one server that points to a Patient on another server is completely legal.)

view this post on Zulip Josh Mandel (Dec 06 2021 at 04:50):

If you're looking for a new capability from the EHR, you could have one of:

  • POST DocumentReference so no auxiliary storage or access control is required. For this use case, that'd be a win.

  • Support for token exchange so apps could request a delegated token specific to a payer, including a token with no actual scopes, and just context. Useful as a general building block but introduces considerable complexity.

view this post on Zulip Grahame Grieve (Dec 06 2021 at 04:51):

I think Lloyd has said that he wants a new capability without any actual new functionality

view this post on Zulip Josh Mandel (Dec 06 2021 at 04:51):

I agree with Lloyd's stated design goal not to rely on anything new from the EHR. In which case just trust the app to manage the data it creates. Which is reasonable since a compromised app will eventually leak all that data no matter where the data are stored (i.e. the compromised app will see them at some point).

view this post on Zulip Josh Mandel (Dec 06 2021 at 04:53):

Set good (i.e., eager to shred) data retention policies in the app, too. That feels doable.

view this post on Zulip John Moehrke (Dec 06 2021 at 13:10):

I agree with Josh conclusion. Seems like you have enough limits that you must just trust the App.

view this post on Zulip John Moehrke (Dec 06 2021 at 13:13):

Note there is a Permission resource that the security wg has been slowly working on that fits the flow that Josh was pointing out. These are B2B rules, so using Consent is not exactly proper. But Permission is intended to carry the kinds of things you are mentioning.. but of course Permission is a R5 (providing some use-cases... hint, hint.. come our way)

view this post on Zulip John Moehrke (Dec 06 2021 at 13:15):

so Permission would be just an application layer declaration; where the similar discussion above using OAuth would be a security-layer "trust" based solution. These are two distinct layers that have pro and con regarding ease vs security.

view this post on Zulip Lloyd McKenzie (Dec 06 2021 at 15:19):

In theory we have a requirement for the EHR to be able to switch apps and still access the work in progress. However, if the "share the token" isn't viable, then we can assert that "if the app changes, you lose all your work in progress". The only risk there is that a well-behaved app that becomes corrupted would have access to everything the app ever had access to (or at least the information that's still out there - 6-12 months worth). Data retention is driven by how long from initial order to completion of billing. We'll see what we can do to keep it tight.

view this post on Zulip John Moehrke (Dec 06 2021 at 19:26):

well, sharing the token is worse. sharing the token is essentially the core of EVERY vulnerability Alissa reported.

view this post on Zulip Cooper Thompson (Dec 06 2021 at 19:34):

IF there were any token sharing, it seems like we'd want the auth server to have a registered list of allowed audiences for the tokens issued, and the client would only share the token with those audiences. Right now, I think SMART on FHIR really only supports a single audience for tokens, but for other (unrelated) integrations, we've also had reason to want to enable controlled token sharing, where the sharing was controlled by pre-coordinating (including signing agreements, etc.) a list of trusted, allowed audiences for the token which the app is expected to respect. I.e. the auth server always knows and controls which parties can get and use the token, and the app is only sharing the token with those trusted and known parties.

view this post on Zulip John Moehrke (Dec 06 2021 at 19:40):

correct

view this post on Zulip Josh Mandel (Dec 07 2021 at 01:03):

Lloyd I'm not follow your comments about losing work in progress. The app should not lose work in progress.

view this post on Zulip Lloyd McKenzie (Dec 07 2021 at 03:22):

If you start with one app filling out the Questionnaire and it saves work in progress and then the EHR transitions to a different app (which doesn't have permission to see data written by the previous app), then you'd lose your work in progress.

view this post on Zulip Jeffy Mathew Jose (Dec 07 2021 at 11:42):

Can we formalize the launch tokens in SMART to carry context around (as in out of EHR)?

At the minimum, the payer could use the opaque launch token (which the app can share) to establish a patient context in EHR and make authorization decisions.

view this post on Zulip John Moehrke (Dec 07 2021 at 12:59):

We "can" do anything, including defining a really poor security solution that will propagate forever. I am resisting defining poor security in a HL7 standard.

view this post on Zulip Jeffy Mathew Jose (Dec 07 2021 at 18:14):

Launch token is just a vehicle to carry patient context.
We need just need to assume that launch tokens are bearer tokens. Unable to see how security is broken.

EHR launch app using SMART launch workflow.
App uses the launch token to complete authorization work flow and establish patient context.

App uses the launch token as subject token (rfc8693) to Payer and get an access token in exchange.
Payer uses the launch token to establish patient context from EHR before issuing access tokens.

Launch tokens seem to fit the bill of comments above without defining new behavior.

view this post on Zulip Josh Mandel (Dec 07 2021 at 23:31):

Launch IDs are opaque to every party besides the EHR. If you are not the EHR, you can't (and shouldn't have to, and shouldn't try to) interpret one.

view this post on Zulip Josh Mandel (Dec 07 2021 at 23:32):

If we're introducing Token Exchange, access tokens would presumably be the input ...

view this post on Zulip adam strickland (Dec 17 2021 at 15:12):

To me, this conversation sound like the Payer is a resource server that is trying to use the EHR as it's authorization server. Would using some of the guidance in RFC8707 (which defines the "aud" parameter but named "resource") be a possible answer:

The authorization server SHOULD audience-restrict issued access
tokens to the resource(s) indicated by the "resource" parameter.
Audience restrictions can be communicated in JSON Web Tokens
[RFC7519] with the "aud" claim and the top-level member of the same
name provides the audience restriction information in a Token
Introspection [RFC7662] response. The authorization server may use
the exact "resource" value as the audience or it may map from that
value to a more general URI or abstract identifier for the given

view this post on Zulip John Moehrke (Dec 17 2021 at 15:56):

I agree that is what it sounds like the payers want to do, but the providers don't want to. Thus deadlock.

view this post on Zulip Lloyd McKenzie (Dec 17 2021 at 16:02):

Not necessarily "providers don't want to", but more "providers won't be technically capable in the desired timeline".

view this post on Zulip Josh Mandel (Dec 17 2021 at 17:32):

And the major distinction here is whether a seconodary resource server should be expected to receive access tokens that are valid at a primary resource server. When both resource servers are managed by the same organization and part of a coherent whole, there's no real concern. But when the "secondary" server is run by an outside organization without strong trust in place, there's no reason it should have to receive access tokens that confer privileges at any other server.

view this post on Zulip Josh Mandel (Dec 17 2021 at 17:33):

With token exchange, an app could complete ean authz flow once, getting user approval... and then generate downscoped tokens intended for use at secondary resource servers.

view this post on Zulip John Moehrke (Dec 17 2021 at 18:48):

and there are thousands of possible payer audience

view this post on Zulip Jeffy Mathew Jose (Dec 29 2021 at 15:53):

Lets try using launch token again

Context: App is trying is share context (specifically patient context) (as received from EHR) to Payer.
Payer has a way to contact EHR and do its business.
Payer trust on App is limited and the payer would like to contain App's access based on given consent at the EHR.
@Lloyd McKenzie, Please correct if these sound wrong

Lets say the app was launched from EHR in SMART launch workflow.
This means the app has an opaque launch token representing the patient in context.
The app uses launch token in SMART workflow (OAuth authorize flow) and get its access token for EHR access.

Now app needs to access something at the payer end.
App should use launch token to establish subject context (per rfc8693) and request for access token at the Payer.
Payer can use the launch token, resolve it at the EHR to get the patient context and issue a access token to the app in context of the patient. (@Josh Mandel , launch token is still opaque and processed only by EHR)

Obviously, this assumes that the launch token may be used by any entity (aka is a bearer token).
Payer get the patient context from EHR (via launch token) and manage authorizations accordingly. App cannot forge tokens and need not share access tokens.
@John Moehrke , Thoughts?

Launch tokens seem to fit just fine..

view this post on Zulip Josh Mandel (Dec 29 2021 at 16:06):

Launch tokens are opaque to every entity except the EHR -- you've preserved this design feature (good!) but also need to keep in mind that a launch token is not an authorization grant, so can't be traded directly for an access token. If a payer was independently authorized to request data from an EHR, then it's indeed possible as you suggest that a recent launch token could be an auxiliary input into a new kind of access token request -- but at that point you're asking EHRs to create a new API for issuing access tokens (i.e. this is something net new, not something that works out of the box with existing implementations), so why not use a more "vanilla" token exchange protocol to accomplish this?

view this post on Zulip John Moehrke (Dec 29 2021 at 16:39):

I am not a SME on the smart launch token. I don't know to what extent the launch token is a formal security token, vs simply a token. If it is typically implemented as simply a token, then it is more likely that your expansion of the use will work. I suspect it is already processed as if it was a bearer token, but don't know the current state.
You mention "Payer has a way to contact EHR and do its business". I presume that this is a formal security trust framework. Meaning that the Payer is recognized as a trusted App, with defined authorizations (likely B2B rights to everything). That this trust is implemented with OAuth flows, which you leverage, specifically these OAuth flows constrict the broad B2B rights for a session scope.
What I would like to see is a threat-assessment. How might this be abused? Expanding the launch token, expands the threats. I understand the desire is to have sessions that are limited to legitimate patient scope. However the solution that comforts the Payer's, likely makes the EHR more at risk. Understanding that risk is important.

view this post on Zulip Lloyd McKenzie (Jan 03 2022 at 04:33):

What we landed on, for now, is just saying that payers must prevent apps from seeing data they have not, themselves, written. This means that if a provider uses App A to start a work in progress, they won't be able to resume that work with App B. However, that's not the end of the world. It also means that if App A was well behaved initially and subsequently becomes corrupted and malicious, it'll have access to data created by the well-behaved version of itself, but we don't have a good way to stop this right now.

view this post on Zulip John Moehrke (Jan 03 2022 at 12:46):

then say that in the "Security/Privacy Considerations" section.


Last updated: Apr 12 2022 at 19:14 UTC