Bring your own credentials
Synq ships with default OAuth credentials so you are running in sixty seconds. Once your Brand has any reputation, swap them for your own. The user will see your company name on Google’s or Apple’s consent dialog instead of Synq’s. This page is how.
What “BYO” actually means
For each OAuth provider, you register an app on the provider’s side
(Google Cloud Console, Apple Developer, Discord Developer Portal,
etc.), get a client_id + client_secret from them, and plug
those into the Brand’s configuration in Synq.
After that, when a user signs in via your Brand:
- The OAuth consent dialog the user sees during sign-in shows your company name (the one registered with the provider).
- Your logo and your privacy policy URL render on the provider’s consent dialog.
- The OAuth tokens issued by the provider are tied to your app, not Synq’s. Your usage counts against your provider quota, not ours.
The model
interface BrandConnection {
brand: string // owning Brand id
type:
| 'google' | 'apple' | 'microsoft'
| 'discord' | 'facebook' | 'x'
| 'telegram' | 'matrica'
enabled: boolean
encryptedConfig: string // AES-256-GCM ciphertext of JSON config
createdAt: string
updatedAt: string
}The (brand, type) pair is unique — at most one connection per
provider per Brand. The config is encrypted at rest; only the
metadata (enabled state, audit info) is queryable from the API.
Per-provider config shapes
Each provider’s connection stores the fields Synq needs to act on the brand’s behalf during a sign-in.
{
type: 'google',
config: {
clientId: '<from Google Cloud Console>',
clientSecret: '<from Google Cloud Console>',
// callbackUrl is derived; you only confirm it on Google's side
}
}Apple
{
type: 'apple',
config: {
teamId: 'XXXXXXXXXX', // 10-char Team ID from Apple Developer
clientId: 'com.acme.web', // Service ID
keyId: 'YYYYYYYYYY', // Key ID from Keys page
privateKey: '-----BEGIN PRIVATE KEY-----\n…\n-----END PRIVATE KEY-----',
}
}Microsoft (Azure AD)
{
type: 'microsoft',
config: {
tenantId: '<your tenant uuid>' | 'common',
clientId: '<application (client) id>',
clientSecret: '<client secret value>',
}
}Discord
{
type: 'discord',
config: {
clientId: '<application id>',
clientSecret: '<oauth2 client secret>',
}
}{
type: 'facebook',
config: {
appId: '<app id>',
appSecret: '<app secret>',
}
}X (Twitter v2)
{
type: 'x',
config: {
clientId: '<x developer portal client id>',
clientSecret: '<x developer portal client secret>',
}
}Matrica
{
type: 'matrica',
config: {
clientId: '<matrica developer console client id>',
clientSecret: '<matrica developer console client secret>',
}
}Telegram
{
type: 'telegram',
config: {
botUsername: 'AcmeAuthBot', // without @
botToken: '<from @BotFather>',
}
}The Telegram bot domain must be bound to
synq.idin BotFather (/setdomain), since that is the domain serving the login widget. One bot per Brand; the default Synq bot only works onsynq.id-hosted sign-in surfaces. See Providers — Telegram.
The callback URL is brand-stable
When you register the OAuth app on the provider’s side, the redirect URI you give them looks like this:
https://synq.id/oauth/<provider>/<brand.oauthCallbackId>/callbackoauthCallbackId is a globally unique, immutable identifier on the
Brand. You can rename the brand, change its slug, change its logo,
move it to a different org — the oauthCallbackId stays. The
redirect URI you gave Google never has to change once configured.
You set it once, on the provider’s side, and forget it.
API — setting up a connection
Setup via the Dashboard is the path for almost everyone. The API path is for automation (Terraform, CI, agents):
PUT /identity/organizations/<orgSlug>/brands/<brandSlug>/connections
Authorization: Bearer <m2m token with IdentityOrgPermission.ConnectionsEdit>
Content-Type: application/json
{
"type": "google",
"enabled": true,
"config": {
"clientId": "1234567890-abc.apps.googleusercontent.com",
"clientSecret": "GOCSPX-…"
}
}Response: the connection metadata (no plaintext config). The
encryptedConfig is stored server-side encrypted at rest.
Toggle without rewriting the config:
PATCH /identity/organizations/<orgSlug>/brands/<brandSlug>/connections/google/enabled
Content-Type: application/json
{ "enabled": false }Delete (reverts to Synq default credentials):
DELETE /identity/organizations/<orgSlug>/brands/<brandSlug>/connections/googleEncryption at rest
Configs are encrypted with AES-256-GCM. The key lives in Synq’s secret store; it never appears in logs, audit records, or API responses. Decryption happens only at sign-in time, only in memory, only on the request path that needs it.
When you rotate a provider credential (a new secret in Google
Console, a new .p8 for Apple), do PUT again with the new value:
- The new ciphertext overwrites the previous one.
- The old plaintext is unrecoverable from Synq’s side.
- The change takes effect on the next sign-in attempt; no users are signed out.
When BYO is required
Some providers practically require BYO before you ship to real users.
| Provider | BYO needed for production? |
|---|---|
| Apple | Effectively yes. Apple’s review team checks. Brand-mismatched consent screens damage trust. |
| Telegram | Yes always. The default Synq bot is hostname-scoped to synq.id; your sign-in surface (typically app.yourdomain.com) needs its own bot. |
| Microsoft | Yes if you ship to Azure AD tenants (their admins will only consent for your app). |
| Recommended before any traffic. Synq defaults will hit quota and the wrong company name appears. | |
| Discord | Recommended; rate limits matter at scale. |
Required if you need email permission for non-developers. | |
| X | Recommended; per-app quotas. |
| Matrica | Recommended; vendor relationship makes BYO cleaner. |
For prototype-stage products, defaults are fine. For production traffic, BYO is the right move.
Provider-by-provider setup guides
The exact click paths for each provider are in Guides:
- Set up Google BYO (~5 min)
- Set up Apple BYO (~15 min — the tricky one)
- Set up Microsoft BYO
- Set up Discord BYO
- Set up Facebook BYO
- Set up X BYO
- Set up Telegram BYO
- Set up Matrica BYO
Mental model summary
- BYO swaps Synq’s defaults for your own provider credentials on a per-Brand basis.
- The callback URL pattern includes the brand’s
oauthCallbackId, so once you set the URL with the provider, it never needs to change. - Configs are encrypted at rest. Decryption is request-path only.
- Apple, Telegram, Microsoft tenants — these are the providers that need BYO before you can take real traffic. Default-friendly providers (Google, Discord, X) can wait until you cross meaningful scale.