From fcdc0bbd749347582a2546aab51ba2df09dab841 Mon Sep 17 00:00:00 2001 From: ravi-signal <99042880+ravi-signal@users.noreply.github.com> Date: Thu, 11 Jun 2026 11:35:20 -0500 Subject: [PATCH] Generate grpc api documentation --- .github/workflows/documentation.yml | 22 ++++++++++++++----- .gitignore | 4 ++++ api-doc/grpc/sabledocs.toml | 2 ++ .../src/main/proto/org/signal/chat/README.md | 14 +++++++++++- .../main/proto/org/signal/chat/backups.proto | 18 ++++++++------- .../main/proto/org/signal/chat/require.proto | 5 +++-- 6 files changed, 49 insertions(+), 16 deletions(-) create mode 100644 api-doc/grpc/sabledocs.toml diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 8aed21aba..e9f106655 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -17,17 +17,29 @@ jobs: distribution: 'temurin' java-version-file: .java-version cache: 'maven' - - name: Compile and Build OpenAPI file + - name: Install gRPC documentation tooling + run: | + sudo apt-get update + sudo apt-get install -y protobuf-compiler + pip install sabledocs + - name: Generate OpenAPI documentation run: ./mvnw compile - - name: Update Documentation + - name: Generate gRPC documentation + run: | + protoc -I service/src/main/proto service/src/main/proto/org/signal/chat/*.proto \ + -o api-doc/grpc/descriptor.pb --include_source_info + cd api-doc/grpc && sabledocs + - name: Push documentation to gh-pages env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - cp -r api-doc/target/openapi/signal-server-openapi.yaml /tmp/ git config user.email "github@signal.org" git config user.name "Documentation Updater" git fetch origin gh-pages git checkout gh-pages - cp /tmp/signal-server-openapi.yaml . - git diff --quiet || git commit -a -m "Updating documentation" + cp api-doc/target/openapi/signal-server-openapi.yaml . + rm -rf grpc + cp -r api-doc/grpc/sabledocs_output grpc + git add -A signal-server-openapi.yaml grpc + git diff --cached --quiet || git commit -m "Updating documentation" git push origin gh-pages -q diff --git a/.gitignore b/.gitignore index 3a91cac56..d0cce5a64 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,7 @@ deployer.log .classpath .settings .DS_Store + +# Generated gRPC documentation build artifacts +/api-doc/grpc/descriptor.pb +/api-doc/grpc/sabledocs_output/ diff --git a/api-doc/grpc/sabledocs.toml b/api-doc/grpc/sabledocs.toml new file mode 100644 index 000000000..dbf4c0836 --- /dev/null +++ b/api-doc/grpc/sabledocs.toml @@ -0,0 +1,2 @@ +main-page-content-file = "../../service/src/main/proto/org/signal/chat/README.md" +markdown-extensions = ["fenced_code", "tables"] diff --git a/service/src/main/proto/org/signal/chat/README.md b/service/src/main/proto/org/signal/chat/README.md index e1b39f38f..5173f29be 100644 --- a/service/src/main/proto/org/signal/chat/README.md +++ b/service/src/main/proto/org/signal/chat/README.md @@ -1,11 +1,23 @@ # Chat gRPC API -Eventually, all chat protocol endpoints will be available via gRPC. + +## Request metadata Clients may provide headers for gRPC requests via [gRPC metadata](https://grpc.io/docs/guides/metadata/) which translates directly to HTTP/2 headers. - Clients should provide a `User-Agent` header on all gRPC requests. - Clients may provide an `Accept-Language` on any gRPC requests. +## Authentication + +To authenticate for a specific signal account + device, clients may provide a [Basic authorization header](https://www.rfc-editor.org/info/rfc7617/) +on the request. The username must be the account identifier encoded in the 8-4-4-4-12 format followed by a '.' +character and then the device id serialized as a string. + +All services either require or forbid providing authentication via an Authorization header. If the service is annotated +with the `require.auth` option `AUTH_ONLY_AUTHENTICATED`, all requests to the service must contain valid authentication +headers. If the service is annotated with the option `AUTH_ONLY_ANONYMOUS` the client must not provide an authorization +header. If provided, the request will fail with a `BAD_AUTHENTICATION` error. + ## Errors In the gRPC protocol all errors are at the request level. That is, errors are returned in response to individual requests and do not impact other H2 streams on the same connection nor terminate the connection. diff --git a/service/src/main/proto/org/signal/chat/backups.proto b/service/src/main/proto/org/signal/chat/backups.proto index bb47ab3cc..c1d84f156 100644 --- a/service/src/main/proto/org/signal/chat/backups.proto +++ b/service/src/main/proto/org/signal/chat/backups.proto @@ -132,17 +132,19 @@ message GetBackupAuthCredentialsResponse { // to the account. // // To register an anonymous credential: -// 1. Set a backup-id on the authenticated channel via Backups::SetBackupId -// 2. Retrieve BackupAuthCredentials via Backups::GetBackupAuthCredentials -// 3. Generate a key pair and set the public key via -// BackupsAnonymous::SetPublicKey +// +// 1. Set a backup-id on the authenticated channel via Backups::SetBackupId +// 2. Retrieve BackupAuthCredentials via Backups::GetBackupAuthCredentials +// 3. Generate a key pair and set the public key via +// BackupsAnonymous::SetPublicKey // // Unless otherwise noted, requests for this service require a // SignedPresentation, which includes: -// - a presentation generated from a BackupAuthCredential issued by -// GetBackupAuthCredentials -// - a signature of that presentation using the private key of a key pair -// previously set with SetPublicKey. +// +// - a presentation generated from a BackupAuthCredential issued by +// GetBackupAuthCredentials +// - a signature of that presentation using the private key of a key pair +// previously set with SetPublicKey. service BackupsAnonymous { option (require.auth) = AUTH_ONLY_ANONYMOUS; diff --git a/service/src/main/proto/org/signal/chat/require.proto b/service/src/main/proto/org/signal/chat/require.proto index bb3bd9d4e..f3b8c5a57 100644 --- a/service/src/main/proto/org/signal/chat/require.proto +++ b/service/src/main/proto/org/signal/chat/require.proto @@ -215,8 +215,9 @@ enum Auth { } // This is duplicated from common.proto because: -// 1. importing would be a circular dependency -// 2. the canonical declaration belongs there +// +// 1. importing would be a circular dependency +// 2. the canonical declaration belongs there enum IdentityType { IDENTITY_TYPE_UNSPECIFIED = 0; IDENTITY_TYPE_ACI = 1;