Coder Social home page Coder Social logo

did-method-web's People

Contributors

awoie avatar dmitrizagidulin avatar ekr avatar gribneau avatar kdenhartog avatar letmaik avatar maxleonard avatar mprorock avatar msporny avatar or13 avatar peacekeeper avatar rhiaro avatar vsnt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

did-method-web's Issues

Use absolute file paths for did:web DIDs.

There is a lot of translation that's done with a did:web URL that feels like it could be simplified. For example, why don't we just require that all DID URL paths are absolute?

did:web:did.example/did.json   // site-wide DID
did:web:did.example/alice.json     // specific entity DID
did:web:did.example/some/arbitrary/path/foo.json   // you can place DIDs at arbitrary paths

I just checked DID syntax, all the above is valid IIUC... why aren't we just doing that instead? It would allow people to just replace "https://" with "did:web:" to get a valid DID Web URL.

RFC: Proposal to standardize email to DID translation

I'd like to see established global identifiers become translatable to new DID identifiers so that people don't have to remember/learn a new identifier. In particular, I find email addresses to be a) one of the few globally accepted and widely spread identifiers and b) built on the DNS system like did:web is.

Therefore, I propose to extend this specification with a translation mechanism from email addresses to did:web DIDs, e.g. [email protected] -> did:web:example.com:john.doe / https://example.com/john.doe/did.json. In my understanding, this translation is mainly relevant for implementers of user interfaces that request identifiers from users to ease their way into SSI and to hide DIDs from them.

I see the following issues with this proposal:

  • DIDs are URIs while email addresses are just identifier-host tuples. Extended features like query parameters and paths can't be represented.
  • Spammers use the technique of iterating identifiers to find accounts on mail servers. A direct correlation between the email address and the DID would allow spammers to iterate publicly readable did.json HTTP endpoints to find valid email addresses. Having said that, this attack vector might exist regardless of this proposal because operators could choose to implement did:web with human-readable identifiers that resemble valid email addresses.

Non-goals:

  • The goal of this proposal is not to make it possible to represent all possible did:web DIDs as email addresses. For example, an email address couldn't represent a DID with a path: ?? -> did:web:example.com:accounts:sales:john.doe

Without the standardization of email to DID translation, implementers could still choose to follow the proposal and try to resolve the corresponding DID. However, chances of success would be higher if the standardization existed and server operators would naturally adopt the mechanism.

I'd love to hear your thoughts on this idea.

Turn w3id.org into a did web resolver with htaccess rewrite

Header set Access-Control-Allow-Origin *
Header set Access-Control-Allow-Headers DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified$
Options +FollowSymLinks
RewriteEngine on

# DID web via redirect

# RewriteRule ^did:web:(.+)$ https://did-web.web.app/api/v1/identifiers/did:web:$1 [R=302,L]

# http://localhost:8080/did:web:vc.did.ai 

RewriteRule ^did:web:([a-zA-Z0-9/.\\-_]+)$ https://$1/.well-known/did.json [R=302,L]

# http://localhost:8080/did:web:did.actor:alice

RewriteRule ^did:web:([A-Z|a-z\.]+)(?::)([a-zA-Z0-9/.\-:\\_]+)$ https://$1/$2/did.json [R=302,L]

# http://localhost:8080/did:web:did.actor:alice:1

RewriteRule ^did:web:([A-Z|a-z\.]+)(?::)([a-zA-Z0-9/.\-:\\_]+)(?::)([a-zA-Z0-9/.\-:\\_]+)$ https://$1/$2/$3/did.json [R=302,L]

# DID web via url rewrite 

# http://localhost:8080/did:web:did.actor:supply-chain:manufacturer:stacy

RewriteRule ^did:web:([A-Z|a-z\.]+)(?::)([a-zA-Z0-9/.\-:\\_]+)(?::)([a-zA-Z0-9/.\-:\\_]+)(?::)([a-zA-Z0-9/.\-:\\_]+)$ https://$1/$2/$3/$4/did.json [R=302,L]

If someone who is better with htaccess and regex can clean this up, we don't need a did web resolver any more.

Need to define URL generation better with the READ operation

There's some odd edge cases that we'll want to be able to specify with greater detail.

For example how should the following DIDs be parsed?

did:web:example.com:
did:web:example.com.:
did:web:example.com..:
did:web:example.com:.:.:path
did:example%2ecom:path

There's probably more, but I think this exemplifies the problem around the different edge cases encountered with URLs

did:web based Identifier for an Issuer, Holder/Subject, Verifier - What is In Scope / Out of Scope or Appropriate / Not Appropriate?

The use of did:web based identifiers assigned to Authoritative Issuers (especially when the issuer is a Sovereign which needs to be public and transparent and visible in identifying itself in digital transactions) such that they can bootstrap from existing infrastructure they already own, operate and trust (DNS and Web) looks to be important for both adoption as well as legitimacy and transparency i.e. Authoritative issuers of credentials and attestations should not, and do not have the luxury of hiding behind pseudonymous or anonymous identifiers; they need to be visible to be held accountable.

However, there may be potential privacy/tracking/correlation concerns in using the did:web method to assign a DID to a holder/subject or a verifier (when that verifier is a person and not an organization).

Does it make sense to limit and constrain the use of did:web to Non-Person Entities (NPEs) i.e. Organizations, Devices etc. ONLY given the ability of an organization to assert control over their Web and DNS infrastructure, and deliberately make the use of did:web for use as an identifier for a person to be out of scope?

Spoofed DNS records aren't an issue

Additionally, implementors should be aware of issues presented by a Spoofed DNS records where the record returned by a malicious DNS Server is inauthentic and allows the record to be pointed at a malicious server which contains a different DID Document. To prevent this type of issue, usage of DNSSEC which is defined in RFC4033, RFC4034, and RFC4035.

The point of having the server authenticate via HTTPS is to not have to rely on DNSSEC here.

SHOULD utilize...

When performing the DNS resolution during the HTTP GET request, the client SHOULD utilize
in order to prevent Man-in-the-middle attacks as well as to prevent tracking of the lookup.

Should utilize what?

User component of a URL

Consider https://foo:[email protected]. How is that supposed to be mapped?

If the user component is not permitted, document that explicitly. Alternatively make an example that shows how this is mapped.

Should a cache be used and if so how long should it be set by default?

This seems like a security considerations aspect but it's become apparent to us that in scenarios where the did:web is being used by an issuer for credentials that are verifiable in offline scenarios a caching strategy is necessary. While this is a more general pattern that needs to be considered such as what's mentioned in the did-resolution draft spec, do we want to make mention of it within this spec as a security considerations aspect? Something to consider here is that by relying on the cache we can help to solve some of the privacy issues from phoning home to get the most recent did document as well.

Clarify integrity protection / use of hashlinks

The spec outlines a basic concept for integrity protection, but it leaves a few important aspects unclear.

did-method-web/index.html

Lines 533 to 551 in 3302643

<section>
<h3>
DID Document Integrity Verification
</h3>
<p>
Additional mechanisms such as <a
href="https://tools.ietf.org/html/draft-sporny-hashlink">Hashlinks</a>
MAY be utilized to aid in integrity protection and verification of the
DID document.
<br />
Under such a scenario the hash of the DID document could be recorded
to a trusted or distributed store and the retriever of the DID
document would generate a hash of the DID document in their posession
with the hash retrieved to ensure that no tampering with the DID
document had occurred.
</p>
</section>

Like, how would the verifier know, which registry is used to store the hashes and who is authorized to add hashes for the corresponding DID?
This should be clearly defined in a spec (did web or an extension to it) and if some of the information can be dynamic (e.g., where the hashes are stored), it may be part of the DID URL itself.
Without further specification how integrity protection works in detail, I don't see how it helps at all to protect integrity of the DID documents.

Is there an implementation of this approach or more details that you could provide?

Define HTTP operations for CRUD

Currently this is all unspecified. We should define this method's CRUD operations in the form of HTTP GET, POST, UPDATE and DELETE (or a subset thereof).

Needs auth

There is no authentication or authorization mechanism applied to the DID Document, leaving it unprotected from modification by an attacker.

Proposal to resolve representation type, file extensions, and mime type issues

We have a number of open issues regarding different representation types, file extensions, and mime types that have been floating around for a while now (#8 #15 #20 #41). I think we are also not in compliance with the IANA Considerations section of the core spec at this point.

Resolving these issues gracefully seems likely to compel us to modify the simple resolution schema. A file named did.json should not contain, for example, CBOR or YAML, and setting the appropriate content type without changing the file extension strikes me as a poor workaround.

Beginning with the core spec, we should be minimally supporting at least two representations:

.didjson
application/did+json

.didjsonld
application/did+ld+json

We can accomplish this by changing the URL resolution logic and relying on webserver configuration to return an appropriate file and set the proper content type by resolving to a directory containing multiple representations rather than a file.

did:web:example.com:charlie

https://example.com/charlie/

In this scenario, the webserver would be configured to recognize a number of index files, each with the appropriate file extension. These file extensions would also need to map to the appropriate content types.

charlie/did.didjson
charlie/did.didjsonld
charlie/did.cbor

We could require that simple json be accepted for all resolutions to support dumb webservers, but recognize the accept request header to prioritize other formats on servers that are capable of handling that logic.

Accept: application/did+ld+json
Accept: application/cbor
Accept: application/did+json

The additional complexity should all be entirely optional so that a simple webserver hosting a simple .didjson file will work today, but there is a path available to those who need other representations.

This would require modifying the URL resolution logic (and also the existing resolvers that have been implemented), but I think it would make more sense in the end.

What does everyone think?

Decide what to do about 'proof' section and other DID Doc Metadata

Signing the DID Document itself (adding an OPTIONAL/recommended proof section, for example) would offer integrity protection / move towards the did docs being self-certifying.

Since the proof property (as well as other metadata fields such as created and updated) were removed from the DID Core spec, we need to make a decision on how to handle these in the did:web method.

Our options:

  1. Put the metadata fields (proof, created etc) into the DID Document itself.
  2. Store not the DID Document in the .json file on the web server, but instead embed it in a structure similar to the DID Resolution Result.

Example structure for option 1:

{
	"@context": "https://www.w3.org/ns/did/v1",
	"id": "did:web:example:com",
	"authentication": [{
		"id": "did:web:example:com#keys-1",
		"type": "Ed25519VerificationKey2018",
		"controller": "did:web:example:com",
		"publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
	}],
	"service": [{
		"id": "did:web:example:com#vcs",
		"type": "VerifiableCredentialService",
		"serviceEndpoint": "https://example.com/vc/"
	}],
	"proof": {
		// signature over the whole DID document would go here.
	},
	"created": "2019-03-23T06:35:22Z",
	"updated": "2023-08-10T13:40:06Z"
}

Example structure for option 2:

{
	"@context": "https://w3id.org/did-resolution/v1",
	"didDocument": {
		"@context": "https://www.w3.org/ns/did/v1",
		"id": "did:web:example:com",
		"authentication": [{
			"id": "did:web:example:com#keys-1",
			"type": "Ed25519VerificationKey2018",
			"controller": "did:web:example:com",
			"publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
		}],
		"service": [{
			"id": "did:web:example:com#vcs",
			"type": "VerifiableCredentialService",
			"serviceEndpoint": "https://example.com/vc/"
		}],
                "proof": {
                    // signature over the whole DID document would go here.
                }
	},
	"didDocumentMetadata": {
		"created": "2019-03-23T06:35:22Z",
		"updated": "2023-08-10T13:40:06Z"
	}
}

Encoding of tilde (`~`)

~ is a safe character in URLs and doesn't have to be encoded, see also https://datatracker.ietf.org/doc/html/rfc3986#section-2.3:

unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"

In DIDs, ~ is not allowed:

idchar = ALPHA / DIGIT / "." / "-" / "_" / pct-encoded

The did:web spec doesn't say much about encoding of the path, only:

Directories and subdirectories MAY optionally be included, delimited by colons rather than slashes.

Being more precise here avoids ambiguities and potentially forging invalid DIDs.

There are roughly two options:

  • Avoid the issue and simply forbid paths containing ~
  • Define how ~ is encoded (and potentially decoded), while not accidently double-encoding the other characters that may already be percent-encoded

Canonical URL algorithm needed for did:web `id` field

What is the canonical URL for a did:web id field. At present, one variation of the future looks like this:

did:web:example.com -> HTTP GET https://example.com/.well-known/did.json

Then the question becomes, what should we expect in the id field for the resulting DID Document. One possibility is this:

  "id": "did:web:example.com"

... but another possibility is this:

  "id": "did:web:example.com/.well-known/did.json"

What if someone specified this as their DID: did:web:example.com/alice.json, but their DID Document states:

  "id": "did:web:example.com/alice"

Is this DID did:web:example.com equivalent to this DID did:web:example.com/?

The current specification does not have an answer to any of these questions, which can be summarized as: What is the canonical URL for a DID Web identifier, if any?

Therefore, if the proposal to use absolute URLs is rejected #52 ... then it raises the question around what a canonical DID Web ID is.

At present, there might be an assumption that there is a canonical URL for a DID Web ID, that is, these are canonical URLs for the examples above:

did:web:example.com
did:web:example.com/alice

If that's the case, then it holds that we have to have at least two special cases when determining if a DID Web ID is valid based on the DID Document we receive:

  • A DID for a domain DID Web ID is found at DOMAIN/.well-known/did.json but the id field in the DID Document MUST be did:web:DOMAIN.
  • A DID for a non-domain DID Web ID is found at DOMAIN/ARBITRARY_PATH/FILE.EXTENSION but the id field in the DID Document MUST be did:web:DOMAIN/ARBITRARY_PATH/FILE (without the extension).
  • Extra rules will be needed if we support re-directs, where you have to remember the initial HTTP GET you did AND there are security concerns if you're sent off of the original domain.

Are there any other special cases we need to consider?

How to handle hostnames with ports?

Now that we support paths (as of PR #5) in our did:web URLs, and we're using the : to encode the / characters for paths, this poses another challenge.

Since we're using the : character for paths, what do we do about the actual most common intended purpose of that character, which is to specify a port number?

So, specifically, say I am a developer who has just fired up a test server on their local machine, which is running on https://localhost:8443 (the https is deliberate of course - I made a self-signed cert for it and everything). This kind of thing happens all the time (it's happening to me right now :) ).

If there's a did:web document residing on that domain (say in /.well-known/did.json), what will that URL look like? According to our rules so far:

did:web:localhost:8443

Except now we're using : (in the did-specific-identifier portion of the url) to encode path fragments. So that URL would "decode" to https://localhost/8443. Not what we want.

So, what are people's thoughts on how to best handle this? @awoie, @OR13 ?

Add language that explicitly deters IDPs (Facebook, Google, MSFT etc.) from abusing subdomain-based IDs

I feel we should add language to the spec that specifically warns against and deters use of did:web with subdomains in ways that are not in keeping with the purpose if DIDs. For example: a large IDP may try to create subdomains on its centralized IDP service domain and 'issue' DIDs to users/customers, which would essentially lock their DID to that provider, the exact opposite of what DIDs were designed to do.

Enable other DID doc content types

A hardcoded file called did.json is not very flexible, and excludes other representations. We should update the spec to use Accept headers on Read. It'd also be better if the requester for Read just fetches the DID as it stands without adding fixed strings or filenames on the end.

Define a mechanism for auditability / change tracking

The read mechanism does not provide any sort of auditability on the DID, which leaves this DID Method open to insider-threat attacks, among others.

(I'm sure there are more grown-up (less single-service-dependent) ways to do this, but we could start by snapshotting the DID doc with archive.org ๐Ÿ˜„ )

Is historical query out of scope of this spec? Is it standardized anywhere else?

Might/should this spec have opinions about or include an optional behavior for historical query?

As @rhiaro cheekily suggested, you can always query
https://web.archive.org/web/20220731132838/https://www.spruceid.com/.well-known/did.json
if you want to read [in human-readable, HTML-wrapped form] what did:web:spruceid.com resolved to on 31 July 2022, but some implementers I've heard from would rather configure their web servers to return that historical DID doc from
did:web:spruceid.com?dateTime=2022-07-31T19:17:47Z

Where would I send an implementer whose system requires this and would like to propose a standard for interop with other historical-query-supporting did:web hosts? Should they PR an entry into the DID Doc Extension Registry for the benefit of other DID hosting solutions that want to harmonize on query?

NB @dmitrizagidulin @peacekeeper since this is debatably more a DID resolution question than a DID web question...

Should it be possible to indicate a port with did:web?

Typically in a web domain a port is a part of the host authority and indicated via a : followed by a number. However due to the way we're currently parsing a resource path we're using the : which maps to a / and changes the resource path. This leaves no way for a port to be specified with the did:web URI. Is this an expected feature or something that's just been overlooked.

@OR13 @dmitrizagidulin @dlongley @rhiaro I'd think you all may have an opinion on this.

QUESTION - Resolving other objects than did.json documents

What is the most appropriate way to resolve other documents than did.json?

We are looking to propose a did:web method for the AnonCreds v1.0 Specification.
The spec is currently implemented with did:[sov|indy|cheqd|cardano].

There are some json objects which need to be publicly stored.
These include:

  • schemas
  • credential definitions
  • revocation registry definitions
  • revocation registry entries

These are then referred to as object ID's for external processing, which are did urls.

Would appending a .json at the end suffice to resolve these objects without conflicts? Meaning if the did url ends with .json, do not append /did.json.
Examples:

  • did:web:<domain>:<checksum>.json
  • did:web:<domain>:v1/schema/<checksum>.json
  • did:web:schema.<domain>:v1/<checksum>.json
  • did:web:<domain>:acme/v1/schema/<checksum>.json

Thoughts, concerns, insults, suggestions and opinions are all welcome!

Should usage of IP addresses be allowed/mentioned within the spec?

I was thinking about it recently and came to realize that if the domain is replaced with an IP address, did:web can be made fairly decentralized while still maintaining all the main benefits around ease of integration. Would it be worth explicitly mentioning it with some examples? From what I can tell with the referenced domain ABNF in [RFC1035], [RFC1123], and [RFC2181] there's no specific mention about how IP addresses could be a domain name (which makes sense). However, if we change the definition to be based around the host/path portion of a URL (thinking referencing WHATWG URL spec here) then it should make this possible.

Thoughts on supporting this?

Support "file" not just "directory" paths

Consider https://foo.example/bar/baz.html.

  • Applying the algorithm, this leads to did:web:foo.example.com:bar:baz.html. Is that intended? If so, add an example to the doc. If not, be clear it shouldn't be. (I believe the entire URL path namespace should be mappable, perhaps even including parameters).
  • Applying the reverse algorithm, the DID document is supposed to be at http://foo.example/bar/baz.html/did.json. Is that intended, turning "file" baz.html into a "directory" all of a sudden? If so, please be clear about it. If not, document an alternative.

Remove the `.well-known` resolution rule

This issue is raised to discuss potential breaking changes to the resolution rules for did web.

I propose we remove the .well-known resolution rule, and instead handle resolution for naked origins as follows:

did:web:example.com - > https://example.com/did.json

This is just another case of the existing path based routing resolution rules...

A 302 redirect can be configured to preserve any existing did documents.

This would simplify the did to url conversion logic by 50% with no loss of the name space.

Representation type

When a DID is resolved to a DID document using the abstract resolveRepresentation function, the resolution result is supposed to include DID Resolution Metadata that includes a contentType for the Media Type of the representation used in the didDocumentStream part of the result.

resolveRepresentation could be implemented for did:web by passing through the HTTP response body as didDocumentStream. But what should the resolution metadata contentType be set to?

In other words, is a did:web DID document expected to be in JSON-LD representation, or in JSON representation?

The specific extension ".json" used in did:web suggests JSON, but in the Create (Register) operation, the DID document is referred to as a JSON-LD file. There is also an (obsolete?) section with a JSON-LD context definition.

Should the HTTP response Content-Type header be used to determine the representation contentType? I think this would be consistent with DID document production/consumption rules:

A conforming producer MUST return the Media Type string associated with the representation after the production process completes.

A conforming consumer MUST determine the representation of a DID document using the Media Type input string.

This would mean however that .json files hosted statically with default settings would be considered JSON rather than JSON-LD. So e.g. JSON-LD did:web DID documents on GitHub Pages would not work.

Or should did:web specify that its DID documents should always be considered one representation or the other?

The difference in representation is relevant as the JSON-LD representation is stricter, for example, its production rules require a specific initial value in the @context property. Strict checking of that property, along with an assumption of JSON-LD representation, caused a problem with one did:web implementation and application: haxxnz/nzcp-rust#1 spruceid/ssi#345. There are also semantic and security reasons why the distinction in representation is important.

There is also some discussion about did:web DID documents having multiple representations: #15, #20 (comment)

Are did:webs that redirect another domain's did:web ok?

I'm wondering if it's wise to do the following:

Bob, who controls bobsdomain.com, wishes to allow Alice to issue VCs on his behalf. Alice controls alicesdomain.com

To allow this, in his DID document Bob puts did:alicesdomain.com:keysForBob#key1 as a verification method. If at some point Bob wants to change the arrangement he can change his did document.

I understand this is valid from the VC spec, but the key rotation/revocation prospects seem a bit dicey among other things. Is there a better way?

I note that Bob could also simply put one of Alice's public keys straight up in his DID document. I don't think this makes anything better though, and it seems a little less honest.

file extension for a json-ld document should be .jsonld

For the domain name w3c-ccg.github.io, the did.json will be available

The extension in the the current version of the did:web spec uses .json in a number of places

But the official extension for a json-ld document is .jsonld

Is this worth changing?

Deny off-domain redirects

It has been proposed that DID Web resolution follows HTTP redirects. If this is true, then there are security implications for blindly following re-directs. For example, if a redirect sends you off of the original domain then it allows an attacker to compromise a site merely by controlling the redirect rules rather than placing a file on the site. If we don't allow redirects off of the original domain, it makes it difficult to move a DID Web ID to a different domain in the future. There are trade-offs each way.

One solution to the problem is to restrict redirects for now until we have more experience for redirecting off of the original domain (we may choose to never do this).

One potential algorithm would be:

  1. Do not allow re-directs.

Another potential algorithm would be:

  1. When resolving a DID Web URL, store the original request URL.
  2. Allow re-directions up to N times (to prevent redirect loops). For each re-direct, ensure that the domain does not change, this includes ensuring port numbers don't change (you can't go from port 80 to port 8080).
  3. The final resolved DID Web DID Document must contain an id field that matches the initial canonicalized DID Web URL (see issue #54).

I haven't put a great deal of thought into all the attack vectors for redirects yet, just trying to propose something that can be refined in this issue.

Specify correct certificate identities

The method specific identifier MUST match the common name used in the SSL/TLS certificate, and it MUST NOT include IP addresses. A port MAY be included and the colon MUST be percent encoded to prevent a conflict with paths. Directories and subdirectories MAY optionally be included, delimited by colons rather than slashes.

As noted in RFC 6125, subjectAltName is the preferred place for the identity.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.