security-primitives

Implements field-level encryption, password hashing, and CSRF protection for OrangeHRM entities.

Updated Jul 23, 2026
One-click install
npx skills add https://github.com/snow-gift111/orangehrm-ai-sdlc-capstone --skill security-primitives-snow-gift111
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: security-primitives
Source: https://github.com/snow-gift111/orangehrm-ai-sdlc-capstone/tree/main/.agents/skills/security-primitives
Command: npx skills add https://github.com/snow-gift111/orangehrm-ai-sdlc-capstone --skill security-primitives-snow-gift111

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Adding encryption to sensitive OrangeHRM columns (SSN, salary, SMTP passwords) requires coordinating migrations, Doctrine EntityListeners, and the Cryptographer class correctly — a mistake like missing the encryptionEnabled() guard or hasChangedField() check causes save errors or double-encrypted data. This Skill documents the exact patterns so you implement them correctly the first time. ## Core Features & Use Cases - Field-Level Encryption: Guides the end-to-end pattern for encrypting new sensitive columns using AES-256-GCM via the Cryptographer class, KeyHandler key file, and EncryptionHelperTrait in EntityListeners, including VARCHAR(512) column sizing. - Password Hashing: Documents the PasswordHash wrapper around PHP's password_hash/password_verify with bcrypt cost 12 for user credential storage and verification. - CSRF Protection: Explains Symfony CsrfTokenManagerTrait usage for login and sensitive form flows. - Use Case: You need to add an encrypted bankAccountNumber column to the Employee entity. Follow the four-step recipe: widen the column in a migration, annotate the entity with a listener, implement the four symmetric encrypt/decrypt callbacks, and guard every call with encryptionEnabled(). ## Quick Start Ask the assistant to add encryption to a new sensitive field on an OrangeHRM entity following the security-primitives pattern.

Frequently Asked Questions about security-primitives

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I add encryption to a new sensitive column in OrangeHRM?

Add a migration sizing the column to VARCHAR(512), annotate the entity with an EntityListeners class, and implement prePersist, preUpdate, postLoad, and postUpdate callbacks that encrypt on write and decrypt on read. Guard every callback with encryptionEnabled() and use hasChangedField() in preUpdate.

How does OrangeHRM hash and verify user passwords?

OrangeHRM uses the PasswordHash class, a thin wrapper around PHP's password_hash and password_verify with PASSWORD_BCRYPT at cost 12. Hash before persisting and verify with password_verify during login; never compare hashes with string equality.

Does OrangeHRM still decrypt legacy AES-128-ECB ciphertext?

Yes, the Cryptographer decrypts both formats automatically. New ciphertext uses AES-256-GCM with a GCMAES256. prefix, while legacy hex-encoded ECB ciphertext is still accepted on decrypt and re-encrypted to GCM only when the row is updated.

What happens if the OrangeHRM crypto key file is lost?

Losing lib/confs/cryptokeys/key.ohrm makes all encrypted fields unrecoverable, since there is no key-rotation mechanism. The key file must be backed up with the database and copied to new installs before upgrading.

Why does my OrangeHRM entity save fail after adding an encrypted field?

The most common cause is a missing encryptionEnabled() guard, which errors on instances without the key file, or a column too small for GCM ciphertext. Ensure the column is VARCHAR(512) and every listener callback checks encryptionEnabled() first.