{"id":40894,"library":"encrypted-attr","title":"encrypted-attr","description":"A library for transparently encrypting model attributes in ORMs or standalone, using AES-256-GCM with 96-bit random nonces and 128-bit authentication tags. Version 1.1.0 is the current stable release, maintained as needed. Supports key rotation via key IDs and additional authenticated data (key id, object id) to prevent substitution attacks. Designed for Node.js ≥4.0, ESM-only? No, CommonJS-based. Differentiator: explicit security and threat models, integration with ORM hooks, and use of standard Node.js crypto.","status":"active","version":"1.1.0","language":"javascript","source_language":"en","source_url":"https://github.com/simonratner/node-encrypted-attr","tags":["javascript","attr_encrypted","encrypted","attribute","property","model","orm"],"install":[{"cmd":"npm install encrypted-attr","lang":"bash","label":"npm"},{"cmd":"yarn add encrypted-attr","lang":"bash","label":"yarn"},{"cmd":"pnpm add encrypted-attr","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Node.js built-in for AES-256-GCM encryption and decryption.","package":"crypto","optional":false}],"imports":[{"note":"Package is CommonJS; ES module import is not supported.","wrong":"import EncryptedAttributes from 'encrypted-attr'","symbol":"EncryptedAttributes","correct":"const EncryptedAttributes = require('encrypted-attr')"},{"note":"encryptAttribute is not a standalone export; must be called on an instance.","wrong":"encryptAttribute(objectId, value)","symbol":"encryptAttribute","correct":"const ea = EncryptedAttributes(...); ea.encryptAttribute(objectId, value)"},{"note":"Same as encryptAttribute; method on an EncryptedAttributes instance.","wrong":"decryptAttribute(objectId, encryptedValue)","symbol":"decryptAttribute","correct":"const ea = EncryptedAttributes(...); ea.decryptAttribute(objectId, encryptedValue)"}],"quickstart":{"code":"const crypto = require('crypto');\nconst EncryptedAttributes = require('encrypted-attr');\n\n// Generate a random 32-byte key and encode as base64\nconst key = crypto.randomBytes(32).toString('base64');\n\nconst encryptedAttributes = EncryptedAttributes(['ssn'], {\n  keys: { k1: key },\n  keyId: 'k1'\n});\n\nconst ssn = '555-55-5555';\nconst encrypted = encryptedAttributes.encryptAttribute('user1', ssn);\nconsole.log('Encrypted:', encrypted);\n\nconst decrypted = encryptedAttributes.decryptAttribute('user1', encrypted);\nconsole.log('Decrypted:', decrypted);","lang":"javascript","description":"Shows stand-alone encryption and decryption of an attribute using random key and an object id for AAD."},"warnings":[{"fix":"Use crypto.randomBytes(32).toString('base64') to generate keys.","message":"Keys must be exactly 32 bytes (256 bits) and encoded as base64.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always provide a unique object ID (e.g., model ID) when encrypting/decrypting per-record attributes.","message":"The key ID and object ID are included as additional authenticated data but are not encrypted; substitution of encrypted values across objects is prevented.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Manage keys via environment variables, vault, or keychain. Never commit keys to source control.","message":"Does not encrypt keys or key IDs; protect them as sensitive credentials.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Combine with secure coding practices (sanitize input, avoid logging secrets) and use transport encryption.","message":"Does not protect against compromised app host or log leaks; this is not a full security solution.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"search_vec":"'-256':17 '1.1.0':30 '128':25 '4.0':60 '96':20 'addit':46 'ae':16 'attack':56 'attr':3,85 'attribut':10,88 'authent':27,47 'base':67 'bit':21,26 'commonj':66 'commonjs-bas':65 'crypto':83 'current':33 'data':48 'design':57 'differenti':68 'encrypt':2,8,86,87 'encrypted-attr':1 'esm':62 'esm-on':61 'explicit':69 'gcm':18 'hook':77 'id':44,50,52 'integr':74 'javascript':84 'key':40,43,49 'librari':5 'maintain':36 'model':9,73,90 'need':38 'node.js':59,82 'nonc':23 'object':51 'orm':12,76,91 'prevent':54 'properti':89 'random':22 'releas':35 'rotat':41 'secur':70 'stabl':34 'standalon':14 'standard':81 'substitut':55 'support':39 'tag':28 'threat':72 'transpar':7 'use':15,79 'version':29 'via':42","created_at":"2026-06-04T18:49:46.751602+00:00","updated_at":"2026-06-04T18:49:46.751602+00:00","problems":[{"fix":"Ensure keys are base64-encoded strings from 32 random bytes.","cause":"Passing a key that is not a base64-encoded string or Buffer.","error":"TypeError: key must be a string or a Buffer"},{"fix":"Use the same key that was used for encryption. If rotating keys, use key id mechanism.","cause":"Encrypted value has been tampered or key has changed.","error":"Error: Unsupported state or unable to authenticate data"},{"fix":"Use const EncryptedAttributes = require('encrypted-attr');","cause":"Attempting to import as ES module default import.","error":"TypeError: EncryptedAttributes is not a constructor"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":null,"cli_version":null,"type":"library","homepage":"https://github.com/simonratner/node-encrypted-attr","github":"https://github.com/simonratner/node-encrypted-attr","docs":null,"changelog":null,"pypi":null,"npm":"encrypted-attr","openapi_spec":null,"status_page":null,"smithery":null,"categories":["storage","security"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-04","next_check":"2026-09-02","install_tag":null}}