Skip to content

sso errors are classified REST/JSON, but the plugin emulates sso-admin, which is JSON 1.1 #758

Description

@scttfrdmn

Spotted during the #739 routing sweep and deliberately left out of it: #739 changes routing,
not error classification.

The mismatch

serviceErrorProtocols["sso"] = errProtoRESTJSON (emulator/error_protocol.go), and
cmd/gen-service-reference's matrix accordingly documents sso as REST/JSON. But
SSOPlugin emulates sso-admin, whose botocore model declares:

  • protocol: json, jsonVersion: 1.1
  • targetPrefix: SWBExternalService

which is why substrate routes it by X-Amz-Target at all (#561) — a REST/JSON service sends
no target.

Why it matters

accessDeniedCodeFor and errorProtocolFor pick the refusal shape from this table. The two
JSON families and REST/JSON do not agree on where the error code lives: JSON 1.1 puts it in
__type (and x-amzn-ErrorType), and a caller's errors.As/ClientError matching keys off
that. Classifying a JSON-1.1 service as REST/JSON is the same class of defect as config
(#580) and pricing (#653) — a refusal a real SDK cannot match, which makes the consumer's
error-handling branch unreachable.

Unlike those two, sso is not missing from the table, so
TestAccessDenied_EveryRegisteredPluginHasAnErrorProtocol passes: it asserts presence, not
correctness. Nothing currently asserts that a classification agrees with the model.

Acceptance criteria

  • sso is classified against its model's protocol/jsonVersion, or the current
    classification is justified in a comment citing what an sso-admin client actually parses.
  • A test pins the refusal shape a real sso-admin client sees — the code readable from
    __type where the model says it should be.
  • The protocol recorded for sso in emulator/routing.go and the generated coverage
    matrix in docs/services.md matches whatever the plugin actually speaks; the routing
    table's Why field currently records the disagreement and should record the resolution.
  • A check exists that a service's error classification cannot silently disagree with the
    protocol recorded for it, so the next mismatch of this kind is a failing test rather
    than a reading of two tables side by side.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions