{"id":598,"date":"2026-03-21T22:52:56","date_gmt":"2026-03-21T14:52:56","guid":{"rendered":"https:\/\/pa.yingzhi8.cn\/index.php\/2026\/03\/21\/auth-credential-semantics\/"},"modified":"2026-03-21T23:08:56","modified_gmt":"2026-03-21T15:08:56","slug":"auth-credential-semantics","status":"publish","type":"post","link":"https:\/\/pa.yingzhi8.cn\/index.php\/2026\/03\/21\/auth-credential-semantics\/","title":{"rendered":"Auth Credential Semantics"},"content":{"rendered":"<h1>Auth Credential Semantics<\/h1>\n<p>This document defines the canonical credential eligibility and resolution semantics used across:<\/p>\n<ul>\n<li><code>resolveAuthProfileOrder<\/code><\/li>\n<li><code>resolveApiKeyForProfile<\/code><\/li>\n<li><code>models status --probe<\/code><\/li>\n<li><code>doctor-auth<\/code><\/li>\n<\/ul>\n<p>The goal is to keep selection-time and runtime behavior aligned.<\/p>\n<h2>Stable Reason Codes<\/h2>\n<ul>\n<li><code>ok<\/code><\/li>\n<li><code>missing_credential<\/code><\/li>\n<li><code>invalid_expires<\/code><\/li>\n<li><code>expired<\/code><\/li>\n<li><code>unresolved_ref<\/code><\/li>\n<\/ul>\n<h2>Token Credentials<\/h2>\n<p>Token credentials (<code>type: \"token\"<\/code>) support inline <code>token<\/code> and\/or <code>tokenRef<\/code>.<\/p>\n<h3>Eligibility rules<\/h3>\n<ol>\n<li>A token profile is ineligible when both <code>token<\/code> and <code>tokenRef<\/code> are absent.<\/li>\n<li><code>expires<\/code> is optional.<\/li>\n<li>If <code>expires<\/code> is present, it must be a finite number greater than <code>0<\/code>.<\/li>\n<li>If <code>expires<\/code> is invalid (<code>NaN<\/code>, <code>0<\/code>, negative, non-finite, or wrong type), the profile is ineligible with <code>invalid_expires<\/code>.<\/li>\n<li>If <code>expires<\/code> is in the past, the profile is ineligible with <code>expired<\/code>.<\/li>\n<li><code>tokenRef<\/code> does not bypass <code>expires<\/code> validation.<\/li>\n<\/ol>\n<h3>Resolution rules<\/h3>\n<ol>\n<li>Resolver semantics match eligibility semantics for <code>expires<\/code>.<\/li>\n<li>For eligible profiles, token material may be resolved from inline value or <code>tokenRef<\/code>.<\/li>\n<li>Unresolvable refs produce <code>unresolved_ref<\/code> in <code>models status --probe<\/code> output.<\/li>\n<\/ol>\n<h2>Legacy-Compatible Messaging<\/h2>\n<p>For script compatibility, probe errors keep this first line unchanged:<\/p>\n<p><code>Auth profile credentials are missing or expired.<\/code><\/p>\n<p>Human-friendly detail and stable reason codes may be added on subsequent lines.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Auth Credential Semantics This document defines the can [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-598","post","type-post","status-publish","format-standard","hentry","category-docs"],"_links":{"self":[{"href":"https:\/\/pa.yingzhi8.cn\/index.php\/wp-json\/wp\/v2\/posts\/598","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pa.yingzhi8.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pa.yingzhi8.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/pa.yingzhi8.cn\/index.php\/wp-json\/wp\/v2\/comments?post=598"}],"version-history":[{"count":1,"href":"https:\/\/pa.yingzhi8.cn\/index.php\/wp-json\/wp\/v2\/posts\/598\/revisions"}],"predecessor-version":[{"id":683,"href":"https:\/\/pa.yingzhi8.cn\/index.php\/wp-json\/wp\/v2\/posts\/598\/revisions\/683"}],"wp:attachment":[{"href":"https:\/\/pa.yingzhi8.cn\/index.php\/wp-json\/wp\/v2\/media?parent=598"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pa.yingzhi8.cn\/index.php\/wp-json\/wp\/v2\/categories?post=598"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pa.yingzhi8.cn\/index.php\/wp-json\/wp\/v2\/tags?post=598"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}