Ensure Authenticated Requester for Business Logic Entry Points
Goal
Every business-logic entry point that requires authentication must include an ensure requester is authenticated business constraint as the first check before any other business logic runs.
This constraint follows the ensure ... formalism. Restate the rule as:
ensure requester is authenticated
Translate that formulation into the syntax, naming, and control-flow conventions of the language in use.
On success this constraint returns the requester id so that downstream business logic can use it directly without re-extracting it from the input. On failure it returns an error indicating that the requester is not authenticated.
What Counts as In Scope
Apply this skill to code that does one or more of these things:
- defines a business-logic entry point that must only run for authenticated requesters
- checks whether the incoming request originates from an authenticated identity before executing business logic
- protects a business operation from unauthenticated execution
- extracts authentication verification logic into a helper, method, or validator inside business logic
Relationship to the Ensure Business Constraints Skill
This skill is a specialization of the general ensure business constraints skill. All rules from that skill apply here except for the success return value. This skill adds specificity about what the constraint checks, where it must appear, and what it returns:
- The constraint is always
ensure requester is authenticated. - The constraint must be the first business constraint checked at the entry point, before any other business constraints run.
- The constraint verifies identity authentication, not authorization, permissions, roles, or eligibility.
- Unlike general business constraints that return a unit-equivalent value on success, this constraint returns the requester id on success to facilitate downstream business logic.
Ensure Rule
Restate the constraint as
ensure requester is authenticatedbefore writing code.- This is the single business rule this constraint enforces.
- Use that formulation to decide the final method name, predicate, branch, or helper shape in code.
Translate the rule into the local language convention.
- Use the project's naming style, such as camelCase, snake_case, PascalCase, or an idiomatic statement form.
- Prefer explicit names such as
ensureRequesterIsAuthenticated,ensure_requester_is_authenticated, or the closest local equivalent. - Keep the code shape idiomatic for the language rather than forcing foreign syntax.
Place this constraint first at every entry point that requires authentication.
- Before any other business constraint, business rule, or business operation.
- The entry point must not proceed to any business logic if this constraint fails.
The constraint returns the requester id on success.
- Return the requester id so that subsequent business logic can use it directly.
- Do not return full user objects, tokens, sessions, or other identity details beyond the requester id.
The constraint fails with an error when the requester is not authenticated.
- Use the project's error convention, such as an error value, thrown domain error, result error, or equivalent failure construct.
- Make the error correspond to the specific violation: unauthenticated request.
Keep the constraint focused on authentication only.
- Do not mix authorization, permissions, roles, or eligibility checks into this constraint.
- Use separate
ensure ...constraints for those concerns.
Input Convention
The authentication constraint needs to receive the requester's authentication information.
When the business-logic-entry-point-execution-context skill is active in the project, the command or query type does not need to carry the requester identity — runWithinContext resolves it internally when creating the context. The constraint retrieves the requester identity from the execution context instead of receiving it as a parameter.
When the execution context skill is not active, the command or query type at the entry point should include the requester identity or authentication token as a field. The constraint receives that field and verifies it represents an authenticated requester. Do not reach outside the entry point's input to obtain authentication state.
Detection Workflow
Find business-logic entry points first.
- Identify command handlers, query handlers, and other business-logic entry points.
- Determine which entry points must only run for authenticated requesters.
Check for the presence of the authentication constraint.
- Look for an
ensure requester is authenticatedcheck or its local equivalent. - Verify that it is the first constraint checked at the entry point.
- Look for an
Check the constraint shape.
- Verify that success returns the requester id.
- Verify that failure produces an error indicating the requester is not authenticated.
Check the constraint focus.
- Verify that the authentication constraint does not also check authorization, permissions, roles, or other concerns.
- Those checks should be separate
ensure ...constraints if needed.
Prefer semantic classification to syntax alone.
- Do not classify a check as the authentication constraint only because it appears first.
- Classify it by whether it verifies that the requester is authenticated.
Writing or Changing the Authentication Constraint
Name the constraint from the business rule.
- Start from the
ensure requester is authenticatedformulation. - Translate it into the local naming convention.
- Start from the
Place it as the first constraint at the entry point.
- Before any other
ensure ...constraint. - Before any business operation or data access.
- Before any other
Return the requester id on success.
- Return the requester id so downstream logic can use it without re-extracting it from the input.
- Do not return full user objects, tokens, session data, or other identity details beyond the requester id.
Return or raise a meaningful error on failure.
- Use an error type or error value that explains that the requester is not authenticated.
- Avoid vague failure shapes when the local style supports explicit errors.
Keep the constraint direct and readable.
- Prefer a straightforward check and early failure path.
- Avoid burying the authentication check behind unrelated branching or side effects.
Examples
TypeScript with execution context and neverthrow:
function ensureRequesterIsAuthenticated(): ResultAsync<
RequesterId,
RequesterIsNotAuthenticated
> {
const ctx = getExecutionContext();
const requesterId = ctx?.requesterId ?? null;
if (!requesterId) {
return errAsync(new RequesterIsNotAuthenticated());
}
return okAsync(requesterId as RequesterId);
}
function createReservationCommandHandler(
command: CreateReservationCommand,
): ResultAsync<CreateReservationCommandHandlerSuccess, CreateReservationCommandHandlerError> {
return ensureRequesterIsAuthenticated()
.andThen((requesterId) => {
// other business constraints and business logic using requesterId
})
}
TypeScript with neverthrow (explicit passing, for languages without execution context):
function ensureRequesterIsAuthenticated(
requesterId: RequesterId,
): ResultAsync<RequesterId, RequesterIsNotAuthenticated> {
// verify the requester is authenticated, return the requesterId on success
}
function createReservationCommandHandler(
command: CreateReservationCommand,
): ResultAsync<CreateReservationCommandHandlerSuccess, CreateReservationCommandHandlerError> {
return ensureRequesterIsAuthenticated(command.requesterId)
.andThen((requesterId) => {
// other business constraints and business logic using requesterId
})
}
TypeScript with exceptions (explicit passing, for languages without execution context):
function ensureRequesterIsAuthenticated(
requesterId: RequesterId,
): Promise<RequesterId> {
// verify the requester is authenticated, throw RequesterIsNotAuthenticated if not
// return the requesterId on success
}
async function createReservationCommandHandler(
command: CreateReservationCommand,
): Promise<CreateReservationCommandHandlerSuccess> {
const requesterId = await ensureRequesterIsAuthenticated(command.requesterId)
// other business constraints and business logic using requesterId
}
Python:
def ensure_requester_is_authenticated(
requester_id: RequesterId,
) -> RequesterId:
# verify the requester is authenticated, raise RequesterIsNotAuthenticated if not
# return the requester_id on success
...
def create_reservation_command_handler(
command: CreateReservationCommand,
) -> CreateReservationCommandHandlerSuccess:
requester_id = ensure_requester_is_authenticated(command.requester_id)
# other business constraints and business logic using requester_id
Kotlin:
fun ensureRequesterIsAuthenticated(
requesterId: RequesterId,
): RequesterId {
// verify the requester is authenticated, throw RequesterIsNotAuthenticated if not
// return the requesterId on success
}
fun createReservationCommandHandler(
command: CreateReservationCommand,
): CreateReservationCommandHandlerSuccess {
val requesterId = ensureRequesterIsAuthenticated(command.requesterId)
// other business constraints and business logic using requesterId
}
Review Questions
When reading or reviewing code, ask:
- Does this entry point require an authenticated requester?
- Is there an
ensure requester is authenticatedconstraint or its local equivalent? - Is it the first constraint checked, before any other business constraint or business logic?
- Does it return the requester id on success?
- Does it produce an error when the requester is not authenticated?
- Does it avoid mixing in authorization, permissions, or role checks?
- Does the entry point receive the requester's authentication information through its declared input parameter?
If the answer is yes, apply this skill.
Report the Outcome
When finishing the task:
- state which entry points were identified or changed
- state where the
ensure requester is authenticatedconstraint was added or verified - state how the constraint was translated into the local language convention
- state that the constraint returns the requester id on success and which failure error shape was used
- state that the constraint is placed before any other business constraint at the entry point