E12062: constraint reference must extend SecurityGate or CORSPolicy
What went wrong
A 'constrain by' clause references a type that exists but does not extend SecurityGate or CORSPolicy. Constraint references must be concrete implementations of one of these two abstract functions.
SecurityGate is an abstract function that receives an HTTPContext and returns an enriched context (or unset to reject). CORSPolicy is an abstract function that receives an Origin string and returns a Boolean (allow/reject).
Worked examples
The [EXAMPLE] section below shows a service constrained by a plain function that extends neither SecurityGate nor CORSPolicy, then by an 'ApiGate' that is a SecurityGate.
Rationale
The constraint system is strongly typed. Only functions that implement the SecurityGate or CORSPolicy contract can be used as constraints. This ensures the router can call them with the correct arguments and interpret their return values correctly.
How to fix it
Ensure the constraint reference extends the correct base: a security gate is a function that 'is SecurityGate' (it takes the HTTPContext and returns the context it lets through, unset to refuse), and a CORS policy is a function that 'is CORSPolicy' (it takes the request's origin and returns a Boolean). A plain function with the right-looking parameters is neither.
See also
- Security posture required: E12050
- Constraint type not resolved: E12060
- Duplicate constraint role: E12064
- SecurityGate abstract function: ek9 -h SecurityGate
- CORSPolicy abstract function: ek9 -h CORSPolicy
- Compilable examples: ek9 -q 1294 (What types are valid in a constrain by clause?) ek9 -q 1293 (What happens when a constrain by reference cannot be re...) ek9 -q 1295 (Why does constrain by X and Y fail when both extend Sec...) ek9 -q 1292 (How does service security posture work with 'open' and ...)
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E12062: constraint reference must extend SecurityGate or CORSPolicy
#!ek9 defines module error.e12062.bad defines function NotAGate() as pure <- rtn as String: "not a security gate" defines service InvalidConstraint for :/api constrain by NotAGate health() as GET for :/status <- response as HTTPResponse: () with trait of HTTPResponse override status() as pure <- rtn as Integer: 200 override content() <- rtn as Bytes: Bytes().withUtf8("ok") override contentType() as pure <- rtn as String: "text/plain" default operator ?
Fixed: Constrain by a function that is a SecurityGate
#!ek9 defines module error.e12062.good defines function ApiGate is SecurityGate -> context as HTTPContext <- rtn as HTTPContext: context defines service GatedService for :/api constrain by ApiGate health() as GET for :/status <- response as HTTPResponse: () with trait of HTTPResponse override status() as pure <- rtn as Integer: 200 override content() <- rtn as Bytes: Bytes().withUtf8("ok") override contentType() as pure <- rtn as String: "text/plain" default operator ?
Questions and answers
These Q&A entries show E12062 and its fix: