-
Notifications
You must be signed in to change notification settings - Fork 452
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
Assessment of VC Schema Alignment with EAS x Ceramic Collaboration #1935
Comments
Just catching myself up to speed here on the passport side, so apologies in advance if I misunderstand the current architecture in any way. I created the EAS x Ceramic guide, so hopefully I'll be able to share some helpful insight there. As you've seen, the example I used in the EAS x Ceramic off-chain attestation guide used a simple MetIRL Schema that only took in a boolean value, while the issuer and recipient are defined when the issuing event occurs. Also, if my understanding of this example implementation is correct, there would presumably be one static issuer of each off-chain passport attestation (unlike the EAS x Ceramic example). Putting the current deployed Passport Stamps V1 definitions aside for a moment and looking only at the values within a passport vc vs my understanding of how one would issue an off-chain passport attestation with the same fields, I'd imagine the schema types needed would just be:
Using ComposeDB, we could define a general attestation interface that each individual provider could implement, thus opening up multiple entrypoints. For example: interface Attestation
@createModel(description: "An attestation interface")
{
publisher: DID! @documentAccount
uid: String! @string(minLength: 66, maxLength: 66)
schema: String! @string(minLength: 66, maxLength: 66)
attester: String! @string(minLength: 42, maxLength: 42)
verifyingContract: String! @string(minLength: 42, maxLength: 42)
easVersion: String! @string(maxLength: 5)
version: Int!
chainId: Int!
r: String! @string(minLength: 66, maxLength: 66)
s: String! @string(minLength: 66, maxLength: 66)
v: Int!
types: [Types] @list(maxLength: 100)
recipient: String @string(minLength: 42, maxLength: 42)
expirationTime: DateTime
revocationTime: DateTime
refUID: String @string(minLength: 66, maxLength: 66)
time: Int!
data: String! @string(maxLength: 1000000)
}
type Types {
name: String! @string(maxLength: 20)
type: String! @string(maxLength: 20)
}
type TwitterVerification implements Attestation
@createModel(accountRelation: LIST, description: "An account attestation")
@createIndex(fields: [{ path: ["attester"] }])
@createIndex(fields: [{ path: ["recipient"] }])
@createIndex(fields: [{ path: ["time"] }])
{
publisher: DID! @documentAccount
uid: String! @string(minLength: 66, maxLength: 66)
schema: String! @string(minLength: 66, maxLength: 66)
attester: String! @string(minLength: 42, maxLength: 42)
verifyingContract: String! @string(minLength: 42, maxLength: 42)
easVersion: String! @string(maxLength: 5)
version: Int!
chainId: Int!
r: String! @string(minLength: 66, maxLength: 66)
s: String! @string(minLength: 66, maxLength: 66)
v: Int!
types: [Types] @list(maxLength: 100)
recipient: String @string(minLength: 42, maxLength: 42)
expirationTime: DateTime
revocationTime: DateTime
refUID: String @string(minLength: 66, maxLength: 66)
time: Int!
data: String! @string(maxLength: 1000000)
} When generating the offchain instances, the data values themselves (the key-values for things like provider, etc) get encoded and signed (EIP712), so the ComposeDB storage definitions are intended to save both the encoded data, as well as the signatures needed to later validate to prove they have not been tampered with, if necessary. In the current Ceramic x EAS repo, you'll notice that the individual user is creating and signing each attestation, while an API is called thereafter to write the attestation to ComposeDB using a static key:did. For each Gitcoin issuance, one difference here is that both the offchain issuance and the writing to ComposeDB would be done server-side by a static key, which would honestly simplify things further. I'm happy to make a branch within our EAS + Ceramic repo to show POC for this if you'd like. IMO, it would a fairly light lift to retrofit the existing code to create offchain passport attestations, and most of the decision-making would be around how to translate those payloads into composeDB schemas that support the type of querying you'll need. |
@mzkrasner Awesome, thank you so much for all this info and for digging into this! So it seems like the main change here is that the attestations do not contain the signature, instead the attestation itself is signed and written to Ceramic by the issuer (us). And so this means that the credential will be part of our Ceramic stream, not the users' streams. This is pretty different from how we issue our credentials now. Currently, the credential itself includes our signature for the credentialSubject, so we can pass the credential around and have anybody store it wherever they want and we can still see that it's a valid credential that we issued. In the current architecture, the user writes this to their Ceramic stream and to our database (validated with the same did-session as their ceramic stream). @mzkrasner have you guys considered some sort of AttestationVC or AttestationByOther (I'm having trouble thinking of a good name right now haha) that would include a signature for some subset of the data? Maybe even include verification of that signature when verifying the offchain attestation? |
More broadly speaking, it seems like we've ended up with two distinct ways of representing passports:
The Attestation could be an attestation about the state of one or more credentials in a passport, or an attestation about the score of a passport at a particular time VCs are basically a credential attestation wrapped in some additional data that can be used to verify it. We don't currently issue VCs for scores. It's easy to go from a VC to an attestation, and also possible to go from an attestation to a pseudo-VC if we either 1. hang on to the signature and tie it with the attestation or 2. we're the issuer and we can re-sign it. We can store both attestations and VCs in any storage mechanism (onchain with EAS, offchain in ceramic or our DB, etc.). With our EAS implementation, we're signing an attestation and then passing this attestation and signature back to the user (this is sort of a pseudo-VC at this point. Now that we've got the EIP-712 credentials, we could just pass those real VCs back to the user instead.). The user writes this onchain, paying for the transaction themself. Our contract verifies the attestation signature and then writes the attestation to EAS. One worry about switching to attestations that we issue directly to ComposeDB from our backend is that we'll be on the hook if Ceramic starts charging a fee. And then we'd have to scramble to re-architect everything, or pay the fees ourselves. |
It would be a simpler system overall if we were just writing directly to our DB and our Ceramic stream from our backend. But I like how it's a bit more self-sovereign at this point. Technically anybody could use our backend to get VCs and then store them wherever they want. I might just be into the narrative, and it may not make a difference in the end. But we sure do like our narratives in crypto haha. |
Hey @mzkrasner thanks for providing this detailed example. From my point of view, both VCs and Off-chain Attestations are self-contained records.
The VCs are issued and signed by our backend, and we can do the same with EAS attestation (I have not tested yet, I have only tested off-chain attestation issues in the browser, but I see no impediment in doing this). So, the 2 formats from my perspective are interchangeable (at least for the current use-case that we have). The current schema that we have for writing passports on-chain however, I think is not well suited for off-chain usage, because we have binary-encoded all the users VCs into a single structure to save gas. So using this schema for off-chain data is hard and I would not go this route. However if we are thinking of creating a attestation schema for a single VC on EAS, then this could really be a replacement for our current VCs. We would then essentially have an attestations and a VC with the exact payload, and each having a signature attesting to that payload, but in a different data structure. There are also other aspects to consider of course (for example revocations- but both formats support this ...). |
@lucianHymer I have created an overview for showing the current data flow: https://app.diagrams.net/#Hgitcoinco%2Fpassport%2F1935_data_flow%2Fdocs%2FOverview.md It's stored in the branch linked to this ticket .... |
@nutrina Okay interesting, I misinterpreted this ticket I think. So I think the VC is self-contained, but the attestation either 1. needs to be written to Ceramic by the attester or 2. we have to make sure to hold on to the signature and pass it around with the attestation (not as part of the attestation itself, the schema doesn't support that), and ensure that some process is verifying this signature (like we're doing now with our onchain attestations). It's sort of just semantic, we can make either work. But if we were to write offchain Attestations of the above format to Ceramic, we would have to do it directly from our backend which is a deviation from how we're handling things currently. But perhaps that's fine, we mostly did it this way to avoid paying users' gas. |
Apologies for my delay - just catching up on this thread now. @lucianHymer - appreciate you explaining the current setup (being that the credentials themselves are signed by Gitcoin, but the stream is controlled by the user). Both VCs and off-chain attestations are tamper-evident, so you could still create the same setup for allowing users to store their own attestations that are signed by passport, and can be passed around and validated where and when validation is needed. EAS's off-chain attestation verification methods function similarly to a VC lib like Veramo, so as @nutrina mentioned, regardless of who owns the Ceramic stream (user vs some static server), the validation calls can tell whether it's been tampered with or not |
I have compared the following scenarios: Scenario A - Gitcoin Passport implements writing VCs to compose DB. This would follow the VC specification (this is already on our roadmap). Scenario B - EAS off-chain attestation: a user writes his stamps as EAS off-chain attestations to ComposeDB (this is currently a hypothetical scenario, we only use EAS for creating on-chain attestations atm.) In both cases we end up having a JSON document that is signed by the same party (the Gitcoin Issuer) that is stored on ComposeDB.
For our use-case, we could also switch from one format to the other (from VC to EAS off-chain attestation). If on the other hand EAS would allow writing off-chain attestations in a VC format (instead of the proprietary one) and preferably not ABI-encode the payload into a byte-string then loading these attestation would be easier, we could essentially introduce support for loading EAS off-chain attestation from Ceramic for example, and stick to the same tooling. To the key questions in this tickets description: Are there elements in the EAS x Ceramic schema that offer significant benefits over our chosen schema?
How does our current VC schema compare in terms of interoperability and future-readiness with the EAS x Ceramic standards?
What are the implications of adopting the EAS x Ceramic schema for our migration strategy and operational continuity?
|
Objective:
To conduct a swift, one-day investigation into our current VC schema against the EAS x Ceramic collaboration, ensuring our approach is aligned with the latest standards and practices before our migration to ComposeDB.
Background:
With the strategic move to Ceramic ComposeDB on the horizon, it's essential to verify that our VC schema is in line with the latest industry developments, specifically the collaboration between EAS and Ceramic.
Key Questions:
Tasks:
Time Frame:
The investigation will be timeboxed to one day, with findings to be presented at the end of the day.
Deliverables:
The text was updated successfully, but these errors were encountered: