CtrlK
BlogDocsLog inGet started
Tessl Logo

guydemo/authguard

Authorization and access control security guidance based on Project CodeGuard — covers RBAC/ABAC/ReBAC, IDOR prevention, mass assignment, and transaction authorization

87

1.45x
Quality

82%

Does it follow best practices?

Impact

93%

1.45x

Average score across 6 eval scenarios

SecuritybySnyk

Passed

No findings from the security scan

Overview
Quality
Evals
Security
Files

task.mdevals/scenario-6/

Payroll Transfer Authorization Flow

Problem/Feature Description

A fintech company runs an internal payroll management tool that lets HR administrators initiate bulk wire transfers to pay employees. The engineering team has built a basic API but is preparing for a security audit before the system handles real money. The security lead is concerned that the current flow allows any authenticated admin to trigger transfers immediately without any secondary verification — a single compromised admin account would be enough to drain the payroll account.

The team wants to introduce a confirmation gate before a transfer is executed: when an admin initiates a transfer, they should receive a verification challenge, review the exact transfer details, and only then be allowed to confirm and execute. The implementation needs to be robust enough to satisfy PCI-DSS aligned reviewers who will specifically look for weaknesses in the verification flow itself.

Output Specification

Produce payroll_api.py containing the full Flask implementation with:

  • An endpoint to initiate a transfer (returns a challenge for the admin to verify)
  • An endpoint to confirm and execute the transfer after verification

Also produce security_notes.md explaining the security design of the verification flow.

Input Files

The following files are provided as inputs. Extract them before beginning.

=============== FILE: inputs/payroll_api.py =============== from flask import Flask, jsonify, request, abort, g import uuid

app = Flask(name)

--- Simulated auth middleware ---

def get_current_user(): """Returns the authenticated admin user from the session.""" # In production, this reads from a verified JWT/session return {"user_id": "admin-001", "role": "hr_admin", "email": "hr@company.com"}

--- Simulated DB ---

_accounts = { "payroll-main": {"balance": 500000.00} }

_employees = { "emp-101": {"name": "Alice Smith", "account": "GB29NWBK60161331926819"}, "emp-102": {"name": "Bob Jones", "account": "GB82WEST12345698765432"}, }

--- Transfer endpoint (current, no step-up) ---

@app.route("/api/transfers", methods=["POST"]) def initiate_transfer(): user = get_current_user() if user["role"] != "hr_admin": abort(403)

body = request.get_json()
employee_id = body.get("employee_id")
amount = body.get("amount")

if employee_id not in _employees:
    abort(404)

# TODO: actually execute the transfer
return jsonify({
    "status": "executed",
    "employee": _employees[employee_id]["name"],
    "amount": amount
})

if name == "main": app.run(debug=True) =============== END FILE ===============

evals

SKILL.md

tile.json