OpenClaw Auth Credential Semantics: The Rules Behind Model Credentials

OpenClaw Auth Credential Semantics: The Rules Behind Model Credentials

OpenClaw auth credential semantics are the rules that decide which model credential may be used, which one must be skipped, and why a failed probe says what it says. That sounds dry until a production agent suddenly stops answering because a token expired, an OAuth refresh moved ownership, or a config route looked like a credential when it was only metadata.

The useful way to read this docs page is not as an auth appendix. It is the contract between setup, diagnostics, model selection, plugin runtime, and agent copying. If those parts disagree, operators get mystery failures. If they share one rulebook, a failure becomes boring enough to fix.

My take: this is one of the least flashy OpenClaw pages and one of the most important for anyone running more than one model account. Model auth is where self-hosting stops being a neat diagram and starts being state, ownership, expiry, refresh, copying, and user identity.

OpenClaw auth credential profiles moving through eligibility checks, OAuth fences, and diagnostic reason codes before reaching a self-hosted AI gateway
AI-generated visual: auth profiles pass eligibility checks before OpenClaw lets them reach model runtime.

The short version: eligibility and resolution are separate

OpenClaw treats credential selection in two passes. First, it asks whether a profile is eligible. Then, at runtime, it resolves the actual credential material for the chosen profile.

That split matters. An auth profile can exist in config and still be unusable. A profile can have a SecretRef and still fail if the reference cannot be resolved. A token profile can include a reference and still be rejected because the attached expiry value is invalid. OpenClaw does not let the presence of a profile name stand in for a usable credential.

The docs say the same semantics are shared by resolveAuthProfileOrder, resolveApiKeyForProfile, openclaw models status --probe, and openclaw doctor auth checks. That is the point. The status command should not claim one thing while the runtime does another. The doctor command should not wave through a profile the resolver later rejects.

For an operator, the mental model is simple:

  • Profile ordering decides the candidate list.
  • Eligibility removes candidates that should not be tried.
  • Runtime resolution obtains the actual key, token, or OAuth material.
  • Diagnostics report the same decision path with stable reason codes.

That last part is the gift. Auth failures are annoying. Auth failures that change names depending on which command you run are worse.

Reason codes are the operator-facing contract

OpenClaw probe results have a status bucket such as ok, auth, rate_limit, billing, timeout, format, unknown, or no_model. When a probe never reaches a model call, it can also report a stable reasonCode.

The important codes are plain enough to act on:

  • excluded_by_auth_order: the profile was left out of the explicit auth order for its provider.
  • missing_credential: no inline credential or SecretRef exists.
  • expired: the token expiry is in the past.
  • invalid_expires: the expiry value is malformed or outside the allowed timestamp range.
  • unresolved_ref: the configured SecretRef could not be resolved.
  • ineligible_profile: the profile does not fit the provider config or has malformed key input.
  • no_model: credentials exist, but OpenClaw could not resolve a model candidate to probe.

These are not decorative error labels. They tell you where to look. missing_credential means check the credential surface. excluded_by_auth_order means check order, not the token body. no_model means the auth side may be fine, but model discovery or model configuration did not produce a probe target.

This is also why operators should avoid “fixing” auth by adding another key at random. If the reason code is about order, expiry, or a missing model, a new key may hide the original problem for a while and make the state harder to reason about later.

Token profiles: the small rules that prevent bad fallbacks

OpenClaw token credentials use type: "token". They can hold an inline token, a tokenRef, or both. A token profile with neither value is ineligible and reports missing_credential.

The expiry rule is stricter than many operators expect. expires is optional, but when it exists, it must be a finite number of Unix epoch milliseconds, greater than zero, and no larger than JavaScript’s maximum Date timestamp. Wrong type, NaN, zero, a negative value, infinity, or an out-of-range value all produce invalid_expires. A valid timestamp in the past produces expired.

One subtle detail is worth calling out: tokenRef does not bypass expiry validation. That is the correct behavior. A secret manager can hide the token bytes from config, but it should not make a known-bad profile eligible just because the value lives somewhere else.

If you are debugging token auth, check these in order:

  1. Does the profile have token or tokenRef?
  2. If expires exists, is it a valid Unix millisecond timestamp?
  3. Is it still in the future?
  4. If using tokenRef, can OpenClaw resolve the referenced secret from the active surface?

That sequence sounds basic, but it prevents a lot of messy debugging. You do not want the runtime to rotate from one invalid token to another just because both profile names exist.

Setup replacement credentials are a safety latch

Setup replacement credentials get their own treatment. They are saved under separate profile IDs with an internal setup descriptor inside the credential payload. Until activation, they cannot enter normal rotation, resolve through an explicit profile pin, or be copied to another agent.

That design protects the current working connection. A new sign-in can be tested without immediately taking over production use. After one successful tool-free turn, setup asks whether to activate it. If the test fails, or the operator declines activation, the saved credential stays inactive and the current connection remains in place.

This may feel cautious, but model auth is one of those places where caution is cheap. A broken replacement credential should not knock a working agent offline. A setup flow should not quietly change the credential used by cron jobs, channel replies, or another agent copy before the operator has seen it work.

There is also a downgrade note in the docs: older runtimes do not enforce the inactive state. Before downgrading, remove saved inactive replacements or restore state from before setup. That is not busywork. It keeps a newer safety marker from being misunderstood by older code.

Agent copy portability: why OAuth is treated differently

OpenClaw has shared auth inheritance. When an agent has no local profile, it can resolve profiles from the shared auth store at runtime without copying secret material into the agent’s own SQLite credential store.

That read-through behavior is different from an explicit copy. When a flow such as openclaw agents add copies credentials, the portability policy is intentionally uneven:

  • api_key profiles are portable unless copyToAgents: false.
  • token profiles are portable unless copyToAgents: false.
  • oauth profiles are not portable by default.

The OAuth rule is the interesting one. Refresh tokens can be single-use, rotation-sensitive, and account-owned in ways that a static API key usually is not. Copying refresh material into agent-local peers can create two owners that both think they are allowed to rotate the same credential. That is a nasty class of bug because it may work once, then fail after the next refresh.

OpenClaw’s docs describe a fenced refresh process. During OAuth refresh, the current generation is replaced by an inert durable marker. Pending markers are ineligible by default. Failed markers are terminal and require the operator to authenticate again. Agent-local peers do not receive copied rotated refresh material. A peer removes its marker and inherits the shared credential only after verifying that the shared credential belongs to the same account.

That last identity check matters. If identity cannot be verified, the peer stays fenced instead of inheriting another account. Annoying? Yes. Safer than letting one agent accidentally pick up another person’s model account? Also yes.

Personal model accounts do not become shared team credentials

OpenClaw also has personal model accounts connected from Settings -> Profile -> Connected accounts. The docs say these credentials are identity-scoped. They do not enter shared auth stores, agent-local auth stores, external CLI mirrors, or global runtime snapshots.

A runtime loads at most the one personal credential selected by its session. If that personal account is unlinked, existing session pins may keep using it, but automatic selection for new sessions should not pick it up. That is the right boundary. A personal account is not team infrastructure just because the same Gateway can see it.

The fallback rule is narrow too. Personal pins keep the same-provider failover policy: ordered shared accounts can be tried after the pinned account fails. They do not turn another person’s personal account into a fallback. Reconnecting can replace only the connecting person’s own credential.

For teams, this is the part to explain before rollout. Shared model accounts belong in shared auth. Personal accounts belong to people. Mixing those concepts creates confusing bills, confusing rate limits, and worse, confusing ownership.

Config-only auth routes are metadata, not secrets

Some auth routes look like credentials but are not stored credentials. The OpenClaw docs call out auth.profiles entries with mode: "aws-sdk". These are routing metadata for providers that use models.providers.<id>.auth: "aws-sdk", including the route a plugin-owned Amazon Bedrock setup writes.

The rule is blunt: do not write type: "aws-sdk" into the credential store. Stored credentials are only api_key, token, or oauth. If a legacy auth-profiles.json has an AWS SDK marker, openclaw doctor --fix moves it into auth.profiles and removes it from the store.

This distinction prevents a bad recovery path. If a selected stored profile disappears, model discovery reports selected_auth_profile_unavailable before consulting dynamic model metadata. Registering a model does not repair missing authentication. You restore the credential or select another configured profile. For config-only AWS SDK routes, the route can remain valid without a stored credential because the SDK chain supplies auth outside the stored credential store.

How auth order shapes probing and runtime behavior

Auth order is not a suggestion box. When auth.order.<provider> or an auth-store order override exists, openclaw models status --probe probes only the profile IDs that remain in the resolved order for that provider. A stored profile omitted from explicit order is not silently tried later. The probe reports excluded_by_auth_order.

That gives operators a clean way to control rotation. If you want one profile out of service, remove it from the order or disable it through the appropriate path, then trust diagnostics to show that it was intentionally excluded.

Session pins add a small exception. A valid session user pin is an explicit per-session preference. OpenClaw tries that profile first even if it is omitted from provider order, then uses ordered same-provider profiles as retry candidates. Cooldowns and disabled windows apply to the affected profile, not to every sibling.

This is where auth semantics meet model failover. OpenClaw rotates auth profiles within the current provider before moving to model fallback. It also treats explicit user session model selections as strict. If a user selected a specific provider and model, OpenClaw should not quietly answer from an unrelated configured fallback just because auth failed.

SecretRefs reduce exposure, but they do not change the rules

The secrets docs make a useful distinction. Plaintext credentials still work, but SecretRefs reduce local plaintext exposure once supported credentials have been migrated and the secrets audit reports no plaintext residue.

Plaintext credentials remain agent-readable if they sit in files the agent can inspect, including openclaw.json, .env, retired auth-profile JSON archives, or generated agents/*/agent/models.json files. SecretRefs move the secret material out of those surfaces, but they do not make an ineligible profile eligible. A missing ref is still missing. An expired token is still expired. An invalid timestamp is still invalid.

That matches OWASP’s broader secrets guidance: standardize secret handling, apply least privilege, automate rotation where it fits, and audit secret access and expiration. In OpenClaw terms, that means using SecretRefs for supported credentials, keeping auth order intentional, and running the built-in diagnostics instead of treating config files as the source of truth.

Troubleshooting checklist for OpenClaw auth credential semantics

When model auth fails, start with the reason code and work outward.

  1. Run openclaw models status --probe and note the status bucket plus reasonCode.
  2. If you see excluded_by_auth_order, inspect the stored order override and auth.order for that provider.
  3. If you see missing_credential, check whether the profile has inline credential material or a valid SecretRef.
  4. If you see invalid_expires, fix the timestamp shape before checking the token value.
  5. If you see expired, refresh or replace the credential through the supported login or setup path.
  6. If you see unresolved_ref, repair the secret provider, reload secrets if needed, then retry the probe.
  7. If you see no_model, move to model configuration and catalog discovery, not secret rotation.
  8. If an agent copy behaves differently from the source agent, check whether it inherited shared auth read-through or received an explicit portable copy.
  9. If OAuth refresh failed, respect the fence. Reauthenticate instead of manually copying refresh material between agent stores.
  10. If a personal account is involved, confirm whether the session is pinned to that person’s credential or using shared ordered accounts.

None of this is glamorous. It is the maintenance work that keeps a self-hosted model setup from turning into folklore.

FAQ about OpenClaw auth credential semantics

What are OpenClaw auth credential semantics?

They are the canonical rules OpenClaw uses to decide whether an auth profile is eligible, how credential material is resolved at runtime, how profiles are ordered, and which reason code appears in diagnostics when a profile cannot be used.

Why does OpenClaw separate eligibility from runtime resolution?

Because a profile name is not the same thing as a usable credential. Eligibility catches missing values, bad expiry fields, expired tokens, incompatible profiles, and excluded order entries before runtime tries to call a model.

Can a SecretRef make an expired token usable?

No. SecretRefs reduce plaintext exposure, but they do not bypass token expiry validation. If expires is invalid or in the past, the profile remains ineligible.

Why are OAuth profiles not copied by default?

OAuth refresh tokens can be single-use or rotation-sensitive. Copying them into multiple agent-local stores can create ownership problems. OpenClaw prefers shared read-through inheritance or explicit provider opt-in when copying is known to be safe.

What does excluded_by_auth_order mean?

It means the profile exists but was omitted from the explicit auth order for that provider. OpenClaw will not silently try it later, and probe output tells you that it was skipped by policy.

Are personal model accounts shared with other users?

No. Personal connected accounts are identity-scoped. They do not enter shared stores, agent-local stores, external CLI mirrors, or global runtime snapshots. Shared accounts can still be configured separately for fallback.

Final take

The best thing about OpenClaw auth credential semantics is that they make auth boring in the right way. A credential is eligible or it is not. A profile is in order or it is not. A SecretRef resolves or it does not. OAuth ownership is fenced instead of guessed. Personal accounts stay personal.

If you run OpenClaw with more than one provider, more than one account, or more than one agent, read the auth semantics page before your first late-night credential failure. Then run openclaw models status --probe, keep openclaw doctor in your toolbox, and migrate plaintext credentials to SecretRefs where the docs support it.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *