Skip to main content
Wildo.ai Coming soon

Choose and configure providers

Keep server credentials out of browser integrations

A provider can contribute server behavior and browser behavior without putting them in the same module. The server side owns credential-aware execution; the browser side carries its public configuration and supported browser code.

A provider has separate server credentials and browser public settings.

Keep server credentials out of browser integrations

A provider can contribute server behavior and browser behavior without putting them in the same module. The server side owns credential-aware execution; the browser side carries its public configuration and supported browser code.

Shared provider identity connects the parts. Their package and runtime boundaries keep their different responsibilities explicit.

Example — The public and private halves of form protection

A website form asks a captcha service for a token in the visitor’s browser, using a public site key. The server checks that token with the service using a secret key the browser never sees. One provider reference joins the two halves.

For engineers

Give each runtime its own module

reCAPTCHA has one module per runtime under the same recaptcha reference. The website module carries only public configuration, and its schema says what must never be put there:

Selected from recaptcha.frontend-website.module.ts; the consent purpose, default public configuration and a comment between these lines are omitted.

providerCapabilities: [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_CAPTCHA],
protocols: [BUILTIN_PROVIDER_PROTOCOL.FRONTEND_SDK],
publicConfigSchema: defineFrontendPublicConfigSchema({
  integrationKind: { kind: FrontendPublicConfigValueKind.STRING, description: 'Which integration: captcha.' },
  websiteRuntime: { kind: FrontendPublicConfigValueKind.BOOLEAN, description: 'Runs on the website surface.' },
  siteKey: { kind: FrontendPublicConfigValueKind.STRING, description: 'The reCAPTCHA v3 SITE key (public by design). Never the secret key.' },
}),

The backend module holds the secret and builds the verifier from it:

Selected from recaptcha.backend.module.ts; metadata, compliance profile, the empty protocol list and the verifier factory are omitted.

providerCapabilities: [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_CAPTCHA],
secretsContract: {
  secretKey: {
    envVarName: 'RECAPTCHA_SECRET_KEY',
    required: true,
    description: 'The reCAPTCHA v3 SECRET key, shared only between this backend and Google, used to verify tokens.',
  },
},

Both declare the same capability, because a captcha is one capability whose token is minted in the page and verified on the server. wildo config sync also refuses to serve a public value equal to any of the environment’s secrets, so a secret pasted into public configuration stops the synchronization instead of reaching a browser.

Not every vendor has two halves. Sign-in and checkout are redirects that run no vendor code in the page, so Google sign-in and Stripe have server modules only, and the page shows the vendor’s name from the server’s configuration.

The backend module belongs to @wildo-ai/external-connectors-private/backend and exposes server runtime contracts and a secrets contract. Secret declarations name the required values; the application supplies those values through the server’s supported credential path. Do not copy secret values into publicConfig or a frontend contribution.

Separate browser data from executable code

Browser integration has two inputs. The application configuration or generated JSON supplies enabled provider data for the service and environment. A code map that configuration synchronization generates for each frontend service supplies executable code from the provider package’s browser facet.

ChannelCarriesWhy it is separate
DataIdentity, public configuration, SDK/component descriptors and CSP footprintCan be serialized for the selected environment.
CodeSDK activation, public-config validation and component loaders where supportedFunctions cannot survive JSON serialization.

hydrateFrontendProviderModules joins those inputs by provider reference. Enabled data without a matching module retains its identity and public configuration, but has no executable SDK and raises a missing-code diagnostic. Bundled code without enabled data remains inactive. Descriptor checks identify stale generated declarations rather than silently treating mismatched data as the current module.

Preserve the boundary in application code

Configuration synchronization writes the code map for each frontend service, src/generated/frontend-providers.generated.ts, importing every provider the service declares from its deliberate browser entrypoint for that surface. The application passes it through the host’s frontend registration option: for the SaaS application host, frontendProviderModules in its startup options, which startup passes into registry hydration alongside the enabled provider data. Rerun synchronization after changing a declaration rather than editing the generated map. Do not import the server package into a React component to obtain metadata. Shared browser-safe metadata exists for that purpose.

Package separation and the public package’s bundle-isolation tests establish an intended boundary, not a magic guarantee that an application can never write an unsafe import. Review custom provider dependencies and the actual browser artifact. Public configuration must remain public, and the server must still enforce access to every credential-backed operation.

See browser activation for the connected contribution and startup example: public settings enter through the companion contribution, while the browser imports its module through a public frontend entrypoint and passes it to its host.

Building a B2B product or an internal tool?

Wildo is not self-service yet. Tell us what you have in mind and we will say plainly whether it fits, and what happens next.