Configured by Android authentication mode
Android Auth coordinates a hosted sign-in flow and its return to the installed application. It is a core, build-derived Android capability, not an optional Library checkbox and not part of Debug Inspector. The package is derived from android.auth.mode when authentication is enabled.
| Mode | User experience | Package implication |
|---|---|---|
browser-sidecar | Hosted sign-in opens through Android Custom Tabs while cApp retains the waiting/return flow | Default cApp Android Auth coordinator |
embedded-sidecar | A hosted first-party sign-in surface inside the coordinator | Optional; some OAuth providers reject embedded sign-in |
system-browser | Ordinary system-browser handoff | Does not select this cApp Auth package |
A Custom Tab can appear as a partial sheet or as a full browser tab. The installed browser controls that presentation. Its size is not a sign-in success signal. It uses the browser process; it is not a Links webpage tab or a promise that OAuth will work inside an iframe.
Before you build
Configure the application's hosted backend and authentication route contract, including its allowed hosted origins and return configuration. Android Auth is the coordinator, not an identity provider or a generic replacement for the backend's user/session implementation.
The initial destination must match the compiled hosted-origin policy. A new provider host, return scheme or native authentication mode can require a new package. Changing a webpage or selecting a different Library draft does not update an installed native bridge.
Confirm the backend is reachable from the device. A development address that works on the build computer is not necessarily reachable on a phone. Follow Android deployment for target configuration rather than putting machine-specific addresses into a public application.
Use a normal data-preserving update for testing. Do not uninstall or clear application storage merely to retry sign-in: that can remove other app-owned data without fixing the hosted-origin or provider problem.
First sign-in and return
- Build and install with authentication enabled and the intended mode selected. Start on an application screen that can display signed-out, pending and signed-in states.
- Use the application's normal Sign in action. cApp creates the ticket and coordinates the browser launch; do not manufacture a completion ticket in application JavaScript.
- Complete or cancel the hosted flow. While the coordinator waits, the application underlay is not an alternate interactive sign-in surface.
- On return, wait for the signed completion/lease verification and refresh the application's account view. Returning to the Activity or loading a provider page is not authentication.
- Confirm the backend-authorised user/session and test a route that requires that session. Also test cancellation, expiration and a second sign-in after logout.
When browser launch fails, the Android surface exposes Try secure login again. The normal browser can be used by the coordinator's supported fallback path when available; application code should not create a second unrelated login attempt merely because the first callback is slow.
Application boundary
The managed bearer remains in the native authentication path. The public capp.auth interface provides status metadata and bounded operations; it is not a token-export API. Use the app's normal authenticated route/SDK transport rather than copying a bearer into local storage, query strings or logs.
| Optional method | Meaning and important limit |
|---|---|
open(payload?) | Start the coordinated user-facing sign-in flow. Resolution is not a universal proof of authentication. |
start(payload?) / status(ticketOrPayload?) | Lower-level ticket workflow. Arguments depend on the compiled backend contract; these are not arbitrary OAuth URLs. |
current() / lease() | Refresh/read public state or redacted lease metadata, possibly asynchronously. A legacy lease object need not contain authenticated. |
user() | Ask the configured backend for the current user. Handle signed-out and unreachable-backend results. |
clear() | Clear the local managed session state; not a universal upstream identity-provider revocation. |
logout() | Request backend logout and clear local state. A local-only fallback (localOnly: true) does not prove a remote session was revoked. |
Await methods even when a particular bridge returns synchronously. Feature-detect the method you need; browser previews and older packages need not expose the same surface. The authentication types describe the deliberately broad compatibility shapes. Do not interpret an arbitrary non-null current() value as backend permission.
Connect a sign-in button
This helper does not launch anything until the person presses the button. Supply the existing app elements; call the returned disposer when their view is removed. The final message deliberately asks for an account refresh rather than claiming a signed-in user from the flow's return value.
<button id="sign-in" type="button">Sign in</button>
<p id="sign-in-status" role="status"></p>function bindSignIn(button, output) {
if (!button || !output) throw new Error('Sign-in elements are missing');
let busy = false;
let disposed = false;
async function run() {
if (busy || disposed) return;
const auth = window.capp?.auth;
if (typeof auth?.open !== 'function') {
output.textContent = 'Sign-in is unavailable in this environment.';
return;
}
busy = true;
button.disabled = true;
output.textContent = 'Complete sign-in in the opened browser.';
try {
await auth.open();
if (!disposed) output.textContent = 'Sign-in returned. Refresh your account status.';
} catch {
if (!disposed) output.textContent = 'Sign-in did not complete. Check the account screen before retrying.';
} finally {
busy = false;
if (!disposed) button.disabled = false;
}
}
button.addEventListener('click', run);
return () => {
disposed = true;
button.removeEventListener('click', run);
// Removing a view is not a request to clear the user's session.
};
}
const disposeSignIn = bindSignIn(
document.querySelector('#sign-in'), document.querySelector('#sign-in-status')
);Use the application's established session-refresh path after return. capp:auth events can update local presentation, but neither an event nor this button helper replaces backend authorisation. Do not log whole ticket, lease, callback or user objects while diagnosing sign-in.
Security and cancellation
The initial native browser URL is restricted to compiled HTTP(S) hosts. Provider redirects take place inside the browser process; the cApp application WebView is not given unrestricted provider navigation. Signed completion still needs verification through the configured status/lease contract.
Closing the coordinator or pressing Android Back ends the visible interaction; it does not mean the identity provider signed the user out, that its cookies were erased, or that a backend operation was reversed. Keep those outcomes separate in the UI. Before starting again after interruption, check the recoverable session state.
For a public distribution, prefer the browser-based provider flow unless you own and have qualified the embedded first-party flow. Never ask users to bypass a provider's sign-in restrictions or accept a callback merely because its text looks successful.
Troubleshooting
| Symptom | Check and next step |
|---|---|
| No Auth option in the Library | Expected: configure Android authentication mode in Build. |
| Provider refuses embedded login | Use the supported browser-based mode; an embedded surface is not a provider-compatibility guarantee. |
| Retry control appears | Check native browser availability, compiled hosted origins and the installed package version, then use the coordinator's retry. |
| Sign-in succeeds in the browser but app stays pending | Check return routing, device connectivity and backend ticket/status verification. Do not accept a browser success page as a substitute. |
current() has no authenticated field | It may be redacted lease metadata. Use the matching bridge contract and the app's backend session check. |
| App is signed out locally but browser still remembers the account | Local lease clearing and the browser's provider session are different scopes. |
Qualify a real Android installation with the intended browser, backend, cancellation path and return scheme. Documentation/browser fixtures do not certify a provider or phone combination.