Custom Courses
A custom course is a named, ordered sequence of practice topics and learn scenarios that you build out of the SecureCodingHub content catalog. Once built, the course can be assigned through the Assignments page the same way you assign a built-in category, and learners consume it inline at /learn/custom/<courseId> as if it were one of the standard courses.
When to build a custom course
The built-in OWASP families are deliberately broad. They make sense as the starting point for organisation-wide rollouts and for compliance evidence packs. But once your team has done one full pass, the next assignment is almost always more targeted — onboarding for backend hires, a focused refresher on a class of vulnerabilities your CodeQL findings keep flagging, a quick ramp on the secure-coding habits for the language stack a team is about to migrate to. That is where custom courses earn their keep: they let you pull exactly the topics and scenarios you want, in the order you want them, into a single named bundle.
Where this lives
Click Custom Courses in the sidebar under the Learning section to land on the list page at /organization/custom-courses. The list shows every course your organization has built, the number of items in each, the number of assignments it is currently referenced by, who created it, and when it was last updated. Click a course row to open the builder for that course; click + New Custom Course at the top right to create one.
Building a course
The builder is a two-pane layout. The left pane shows your current item list with drag-handle reordering and a per-row remove control. The right pane is the picker — a tree of categories, modules, topics, and scenarios drawn from the live content catalog. The Add buttons let you bring in items at any granularity:
| Add at | Effect |
|---|---|
| Topic | Adds a single practice topic. Learners see all the challenges inside it, in their own preferred language per Stack Preferences. |
| Scenario | Adds a single learn scenario. Learners go through the step-by-step walkthrough as in Learn Mode. |
| Module | Expands the module to its constituent topics and adds each one as a separate item (so you can reorder them or remove specific ones afterwards). |
| Category | Same as Module but at the OWASP-family level. Useful as a starting point you then trim. |
Save the course at any time; partial saves are allowed. The Name is the only required field. Optional Description, Icon, and Color fields let you brand the course inside the learner UI.
Assigning a custom course
From Assignments → New Assignment, pick Custom as the Content Area and select your course from the dropdown. The rest of the assignment form behaves the same way as for built-in content — pick an assignee (user, team, or whole organization), pick a deadline, choose mandatory or optional, and create. The assignee's progress is tracked item-by-item against the course's content, and the Assignment Detail page rolls those up into the same completion percentage the OWASP-tracked assignments use.
Editing and deleting
Open a course to change its name, description, icon, color, or item list. Item changes apply immediately to active assignments — adding an item raises the denominator for in-flight learners, removing one lowers it. Reordering does not affect completion math; it only changes the order in which the items render in the learner UI.
The Delete action sets the course inactive. It stops appearing in the list, in the assignment-creation picker, and in the learner consumption surface. Historical assignments that reference the course continue to report their existing progress; they just won't accept new assignees once the course is gone.
Programmatic access
Everything in the admin UI is also reachable from the public API — see API → Custom Courses for the JSON request and response shapes. Common automations include syncing a list of curated courses from a versioned source-control repository, and building per-team onboarding courses programmatically from team metadata.