# SSO, OAuth/OIDC and token trust

Distinguish reading JWT content from validating it. Review issuer, audience, time, redirects and consent in a complete trust chain.

Original AI-assisted SecNet educational content. Fictional local examples; not a standards provider publication, endorsement or compliance evidence. Page exercises do not create account progress.

Sources checked: 2026-10-21

## Define the boundary of SSO

SSO provides a sign-in experience across applications; it does not guarantee identical authorization and session policies. OAuth is an authorization framework, while OIDC adds an identity layer. ID tokens and API access tokens have different purposes. Harbor inventories the identity provider, application owner, accepted tenant/issuer and data scope separately. This lesson establishes no SSO connection. A successful connection indicator does not prove that every application validates the correct token and enforces object permissions. Review each relying application’s trust boundary rather than treating federation as universal access approval.

## Decoding is not validation

Readable JWT claims are not automatically trustworthy roles. Appropriate signature, algorithm/key selection, expected issuer and audience, time conditions and protocol-dependent checks are needed. Design trusted metadata retrieval and key rollover separately. Boolean fields here assert that evidence exists; they perform no cryptographic validation. The local access desk neither accepts nor decodes JWTs. Learners explain which application evidence is needed for each check rather than fabricating a signature-validation result. Token content should not be pasted into a public learning page or an untrusted external decoding service.

## Redirects and response binding

RFC 9700 updates OAuth security practice. Exact redirect matching, appropriate PKCE and request/response binding matter, with details depending on protocol and client type. OIDC nonce and OAuth state are not interchangeable concepts. Harbor includes no working exploit or token exchange; its review plan defines negative cases such as invalid redirects and mismatched context. Real applications should use maintained protocol libraries and the relevant official validation rules. Passing the educational evidence model establishes neither correct protocol implementation nor resistance to every OAuth attack.

## Application consent and scope

Application registration does not establish that every permission is needed. Delegated and application-only access have different risk implications. Record tenant, data source, permission, consent authority and periodic review. Removing unnecessary scope involves existing consent and token behavior, not just hiding an app tile. Harbor workpapers capture the consent owner, business rationale and validation needed after revocation. This package consents to no real third-party application and changes no SSO configuration. Treat consent as a governed authorization decision rather than an incidental registration checkbox.

## Working sequence

1. Separate SSO and token purposes.
2. Record trusted issuer, audience and key sources.
3. Plan redirect and response-binding tests.
4. Review application scope and consent owner.
5. Separate actual implementation evidence from assumptions.

## 1. The JWT is readable

Readable claims establish no signature, issuer, audience or time validation. This Boolean evidence model cannot replace actual cryptographic implementation; production needs a trusted library.

This code is a local policy model; it does not replace actual authentication, token validation or live permission tests.

### Weak implementation
```js
s => s.jwtDecoded === true
```

### Corrected implementation
```js
s => s.jwtDecoded === true &&
  s.signatureVerified === true &&
  s.issuerAllowed === true &&
  s.audienceChecked === true &&
  s.timeChecked === true
```

### Synthetic input and actual model output
```json
{
  "before": [
    {
      "name": "documented-case",
      "input": {
        "jwtDecoded": true,
        "signatureVerified": true,
        "issuerAllowed": true,
        "audienceChecked": true,
        "timeChecked": true
      },
      "expected": true,
      "observed": true,
      "matched": true
    },
    {
      "name": "missing-signatureVerified",
      "input": {
        "jwtDecoded": true,
        "signatureVerified": false,
        "issuerAllowed": true,
        "audienceChecked": true,
        "timeChecked": true
      },
      "expected": false,
      "observed": true,
      "matched": false
    },
    {
      "name": "missing-audienceChecked",
      "input": {
        "jwtDecoded": true,
        "signatureVerified": true,
        "issuerAllowed": true,
        "audienceChecked": false,
        "timeChecked": true
      },
      "expected": false,
      "observed": true,
      "matched": false
    }
  ],
  "after": [
    {
      "name": "documented-case",
      "input": {
        "jwtDecoded": true,
        "signatureVerified": true,
        "issuerAllowed": true,
        "audienceChecked": true,
        "timeChecked": true
      },
      "expected": true,
      "observed": true,
      "matched": true
    },
    {
      "name": "missing-signatureVerified",
      "input": {
        "jwtDecoded": true,
        "signatureVerified": false,
        "issuerAllowed": true,
        "audienceChecked": true,
        "timeChecked": true
      },
      "expected": false,
      "observed": false,
      "matched": true
    },
    {
      "name": "missing-audienceChecked",
      "input": {
        "jwtDecoded": true,
        "signatureVerified": true,
        "issuerAllowed": true,
        "audienceChecked": false,
        "timeChecked": true
      },
      "expected": false,
      "observed": false,
      "matched": true
    }
  ]
}
```

## 2. We use OAuth

Using OAuth does not establish correct redirect and PKCE checks. Review response binding too; the model performs no actual protocol exchange.

This code is a local policy model; it does not replace actual authentication, token validation or live permission tests.

### Weak implementation
```js
s => s.oauthUsed === true
```

### Corrected implementation
```js
s => s.oauthUsed === true &&
  s.pkceValidated === true &&
  s.redirectExact === true &&
  s.responseBound === true
```

### Synthetic input and actual model output
```json
{
  "before": [
    {
      "name": "documented-case",
      "input": {
        "oauthUsed": true,
        "pkceValidated": true,
        "redirectExact": true,
        "responseBound": true
      },
      "expected": true,
      "observed": true,
      "matched": true
    },
    {
      "name": "missing-pkceValidated",
      "input": {
        "oauthUsed": true,
        "pkceValidated": false,
        "redirectExact": true,
        "responseBound": true
      },
      "expected": false,
      "observed": true,
      "matched": false
    },
    {
      "name": "missing-redirectExact",
      "input": {
        "oauthUsed": true,
        "pkceValidated": true,
        "redirectExact": false,
        "responseBound": true
      },
      "expected": false,
      "observed": true,
      "matched": false
    }
  ],
  "after": [
    {
      "name": "documented-case",
      "input": {
        "oauthUsed": true,
        "pkceValidated": true,
        "redirectExact": true,
        "responseBound": true
      },
      "expected": true,
      "observed": true,
      "matched": true
    },
    {
      "name": "missing-pkceValidated",
      "input": {
        "oauthUsed": true,
        "pkceValidated": false,
        "redirectExact": true,
        "responseBound": true
      },
      "expected": false,
      "observed": false,
      "matched": true
    },
    {
      "name": "missing-redirectExact",
      "input": {
        "oauthUsed": true,
        "pkceValidated": true,
        "redirectExact": false,
        "responseBound": true
      },
      "expected": false,
      "observed": false,
      "matched": true
    }
  ]
}
```

## 3. Registered application

Registration does not establish necessary, approved scope. Permissions, tenant context and consent ownership must be explicit before broad application access can be justified.

This code is a local policy model; it does not replace actual authentication, token validation or live permission tests.

### Weak implementation
```js
s => s.appRegistered === true
```

### Corrected implementation
```js
s => s.appRegistered === true &&
  s.permissionsReviewed === true &&
  s.tenantContext === true &&
  s.consentOwned === true
```

### Synthetic input and actual model output
```json
{
  "before": [
    {
      "name": "documented-case",
      "input": {
        "appRegistered": true,
        "permissionsReviewed": true,
        "tenantContext": true,
        "consentOwned": true
      },
      "expected": true,
      "observed": true,
      "matched": true
    },
    {
      "name": "missing-permissionsReviewed",
      "input": {
        "appRegistered": true,
        "permissionsReviewed": false,
        "tenantContext": true,
        "consentOwned": true
      },
      "expected": false,
      "observed": true,
      "matched": false
    },
    {
      "name": "missing-consentOwned",
      "input": {
        "appRegistered": true,
        "permissionsReviewed": true,
        "tenantContext": true,
        "consentOwned": false
      },
      "expected": false,
      "observed": true,
      "matched": false
    }
  ],
  "after": [
    {
      "name": "documented-case",
      "input": {
        "appRegistered": true,
        "permissionsReviewed": true,
        "tenantContext": true,
        "consentOwned": true
      },
      "expected": true,
      "observed": true,
      "matched": true
    },
    {
      "name": "missing-permissionsReviewed",
      "input": {
        "appRegistered": true,
        "permissionsReviewed": false,
        "tenantContext": true,
        "consentOwned": true
      },
      "expected": false,
      "observed": false,
      "matched": true
    },
    {
      "name": "missing-consentOwned",
      "input": {
        "appRegistered": true,
        "permissionsReviewed": true,
        "tenantContext": true,
        "consentOwned": false
      },
      "expected": false,
      "observed": false,
      "matched": true
    }
  ]
}
```

## Exit evidence

- Application/issuer/audience/token-purpose trust matrix.
- Negative validation plan and permission/consent review record.

## References

- [RFC 9700 · OAuth 2.0 Security Best Current Practice · January 2025](https://www.rfc-editor.org/rfc/rfc9700.html)
- [OpenID Connect Core 1.0 · Errata set 2 · December 2023](https://openid.net/specs/openid-connect-core-1_0.html)
