Права, проверени преди действието
ComOps носи 120 права и девет заредени роли, които ги ползват: администратор, мениджър, търговец, склад, счетоводител, наблюдател, доставки и две портални роли, едната за клиенти, другата за доставчици. Ролите са ваши и ги прекроявате както ви е нужно. Самата проверка е от страната на сървъра, на нивото на действието: кодът, който създава фактура, пита дали влезлият потребител има право да създава фактури, преди да запише каквото и да било, и отказва, ако отговорът е не. Скриването на меню е удобство за потребителя; то не е контролът.
Влизане в системата
Паролите се хешират с bcrypt при цена 12. Всеки потребител може да включи вход в две стъпки с обичайно приложение за еднократни кодове по RFC 6238 и получава кодове за възстановяване за еднократна употреба, които също се пазят хеширани. Повторните неуспешни опити се ограничават и по адрес, и по акаунт, а акаунтът се заключва след праг, който вие задавате, така че и вярна парола при заключен акаунт се отказва. Бисквитките на сесията се задават с httponly и secure и се ограничават със SameSite, а обработката на сесиите работи в строг режим, така че идентификатор, който сървърът не е издавал, не се приема.
Одобрения, които не заяждат
Когато едно действие изисква нечие съгласие, одобрението е процес в системата, а не имейл. Одобряващ, който отсъства, преотстъпва стъпката си на посочен колега, а стъпка, която стои твърде дълго, ескалира сама: всеки процес носи момента, в който просрочва, а фонова задача ги събира и ги придвижва напред. Така отсъствието забавя одобрението, вместо да го спре, а и преотстъпването, и ескалацията остават в записа.
Одитен дневник, който базата защитава
Всяка одитирана промяна се записва с хеш SHA-256, взет върху самия ред заедно с хеша на предишната промяна по същия запис, така че вписванията образуват верига: променете едно и всеки следващ хеш спира да съвпада. Прилагането на това е отделно и стои по-надолу: таблицата с одита носи тригери в базата, които отхвърлят обновяване и отказват изтриване, така че гаранцията не зависи от това дали приложението се държи прилично. Проверяваща задача минава цялата верига всяка нощ, пази проверения връх във файл извън уеб директорията и сигнализира, когато веригата или този файл не съвпадат. По-лекият поток от събития, който хората четат всеки ден, е съвсем друга таблица, така че разчистването му не може да стигне до одитния запис.
Контроли около числата
Приключеният период е заключен, а отключването е обвързано с право, което повечето хора нямат, изисква писмена причина и само по себе си влиза в одитния дневник заедно с тази причина. До заключванията вървят проверките за цялост: минавания само за четене, които преизчисляват какво трябва да казват книгите и излизат с код за грешка, когато не съвпадат, така че заобиколен контрол излиза наяве като провал, а не като изненада в края на годината. Данните стигат до базата през подготвени заявки като правило на кода, а до екрана през една функция за екраниране, която изгледите извикват, така че нито единият, нито другият път зависи от това някой да си спомни.
Качени файлове, скриптове и тайни
Качен файл се приема само ако разпознатият му тип е сред разрешените, а типът се чете от самия файл, а не от името, което браузърът е подал; записва се под случайно име, а за изтеглянето му се иска право. Интерфейсът на приложението не зарежда нищо от трета страна: няма аналитика, няма мениджър на етикети, няма шрифт или скрипт от чужд домейн, тоест външна промяна не може нито да наблюдава хората ви, нито да се изпълни в тяхната сесия. Данните за достъп до базата и ключовете стоят във файл извън уеб директорията, така че грешка в настройката на уеб сървъра не може да ги разкрие. Останалото от картината на работа е на страницата за хостинг.