🗒️ Change Log
All notable changes to this project will be documented in this file.
v2.3.8 - 05/28/2026
Added
- Added public
GET /v2/changelogendpoint that rendersCHANGELOG.mdas HTML (no authentication required). - Added a Changelog link on the API docs page (
/v2/docs) via a custom ReDoc viewer, with matching navigation on the changelog page back to the API reference. - Bundled
CHANGELOG.mdin the application Docker image so the changelog is available in deployed environments.
Changed
- Added
markdownto base requirements for changelog HTML rendering; addedtypes-Markdownto dev requirements for mypy.
Fixed
- CM-823:
PUT /auth/passwordnow revokes all existing Cognito sessions and clears the cached auth entry for the user on success, covering both the authenticated change-password path and the reset-token / forgot-password path. Previously a successful password update left existing access and refresh tokens valid until natural expiration, so a stolen token could continue to be used after the legitimate user reset their password. - CM-820:
GET /{group_id}/data/{path}now appliespath_filterwith true filter-then-paginate semantics. The query walks pages of raw DynamoDB items, accumulating regex matches untillimitmatches are found, the data is exhausted, or a newMAX_PATH_FILTER_SCAN_ITEMSsafety cap (10,000) is reached. Previously DynamoDB's ownlimittruncated the underlying item set before the regex ran, so matches living past the page boundary were silently dropped (e.g. a match at position 101 with the defaultlimit=100returned an empty result). - CM-820:
limitis now re-validated after the raw query-string fallback path, closing a gap wheresetattrskipped the pydantic field validator and let values outside[1, 1000]through.
v2.3.7 - 05/28/2026
Fixed
- Fixed
GET /users(and other list endpoints usingGetParams) returning 400 when boolean query flags are sent with an empty value (e.g.?object_count=). Pydantic v2 was applying strict bool parsing beforefield_validator(mode="before"); query bools now use a sharedQueryBooltype so empty values are treated astrue, matching documented v1-style clients.
v2.3.6 - 05/28/2026
Fixed
- Fixed
GET /{group_id}/data/{path}validation error whenpaths_onlywas requested withcascade=false(or when raw query coercion left boolean flags unparsed). Non-cascade mode incorrectly took the first path or count scalar and passed it toDataAtPath.paths, which expects a list.
Security
- Security upgrade: bumped idna from 3.7 to 3.15
v2.3.5 - 05/18/2026
Changed
- Upgraded Django from 4.2.29 to 5.2.14.
- Refactored Pydantic v2 and django-pydantic-field usage across the v2 API: updated field and model validators, aligned validation error handling so responses use consistent
Statuspayloads, refreshed schema and model definitions, and adjusted migrations for django-pydantic-field compatibility. - Aligned
isortwith Black (line_length = 100) and set skip paths for migrations and tooling directories.
Fixed
- Fixed Data API query fallback coercion for
path_filterandlast_evaluated_keywhen raw query strings bypass schema parsing.path_filteris now compiled to regex before use, andlast_evaluated_keyis now JSON-decoded before DynamoDB queries, preventingAttributeError: 'str' object has no attribute 'search'and invalid starting keyValidationExceptionerrors. - Added targeted unit tests covering fallback coercion for
path_filterandlast_evaluated_key, plus validation behavior for invalidlast_evaluated_keyJSON.
Security
- Bumped cryptography, Pillow, requests, and related packages via pip-compile; pinned Django 5.2.14 and urllib3 2.7.0 for upstream security fixes.
v2.2.40 - 03/19/2026
Changed
- Security: Bumped Django from 4.2.28 to 4.2.29 for security fixes.
- Security: Upgraded PyJWT from 2.10.1 to 2.12.0+ to address GHSA-752w-5fwx-jx9f.
- Security: Removed python-jose from dev dependencies to eliminate ecdsa vulnerability (GHSA-wj6h-64fc-37mp); moto 5.1+ uses joserfc instead.
v2.2.39 - 03/19/2026
Changed
- Collapsed SMS MFA enabling and phone verification into a single two-phase flow on
PUT /auth/mfa/sms. Phase 1 (noverification_code) sets the phone number in Cognito and triggers Cognito's built-in OTP delivery via SMS. Phase 2 (same call withverification_code) verifies the OTP with Cognito, then enables SMS MFA. On verification failure the phone is removed from Cognito;pending_phone_numberis preserved so the user can request a new OTP without re-entering their number. - Removed
POST /account/sms/verificationandPUT /account/sms/verificationendpoints. Phone verification is now handled exclusively through the two-phasePUT /auth/mfa/smsflow. phone_number_verifiedis now set toTrueat MFA enable time (phase 2), eliminating the previous inconsistency where Cognito considered the phone verified but the application DB did not.set_preferredis now applied in Phase 2 where it takes effect; Phase 1 ignores it.
Added
- Added
verification_codefield toAddSmsMfaForm(phase 2 confirmation code). - Added
SmsMfaVerificationPendingresponse schema returned by phase 1. - Added
pending_phone_numberfield toCmUserto track the phone number awaiting OTP confirmation.
Fixed
- Fixed
InvalidParameterExceptionfrom Cognito when cleaning up after a failed verification:phone_number_verifiedis a Cognito-managed attribute and cannot be explicitly deleted; onlyphone_numberis now passed to the delete call.
v2.2.38 - 02/19/2026
Fixed
- Fixed issue where refresh token grants were allowed when MFA is required by org policy but user hasn't set up MFA. Users must now log in with username and password to complete MFA setup before refresh tokens can be used.
Changed
- Removed SMS bridge workaround logic from MFA disable endpoints. Software MFA can now be disabled directly without requiring SMS as an intermediate step, even when MFA is required by org policy.
v2.2.37 - shipped in v2.2.38
Added
- Added
exclude_adminsparameter to GET /users endpoint. Whenexclude_admins=Trueand the requester is not an org admin or project admin, the endpoint excludes org admins and project admins from results when filtering bygroup_idorproject_id. This allows non-admin users to see only users with explicit access, excluding those with implicit admin access.
v2.2.36 - shipped in v2.2.38
Changed
- Include
role_idsin GET /users list endpoint response to enable client-side filtering by role count (e.g., distinguishing regular doctors from facility admins who hold multiple roles) - Security: Bumped Django from 4.2.27 to 4.2.28 to address GHSA-2mcm-79hx-8fxw, GHSA-mwm9-4648-f68q, GHSA-6426-9fv3-65x8, GHSA-gvg8-93h5-g6qq
v2.2.35 - shipped in v2.2.38
Changed
- Prevent non-admins (org and project) from deleting/suspending admin users
v2.2.34 - shipped in v2.2.38
Changed
- Prevent non-admins (org and project) from patching admin users
v2.2.33 - shipped in v2.2.38
Changed
- Security: Bumped orjson to 3.11.6 to address GHSA-hx9q-6w63-j58v
Fixed
- Fixed software MFA setup returning 500 Internal Server Error when an empty or too-short MFA code is provided; now returns 400 Bad Request with a user-friendly message.
v2.2.32 - 01/17/2026
Changed
- Edit cognito exception handling in sms verification.
v2.2.31 - shipped in v2.2.32
Changed
- Edit message of Bad Request to "Invalid Code" when a logged in user verifies SMS MFA with .
v2.2.30 - shipped in v2.2.32
Changed
- Return a Bad Request when a logged in user verifies SMS MFA.
v2.2.29 - shipped in v2.2.32
Changed
- Group admin support for sending recovery emails and resetting MFA for users within their groups
- Group admins cannot perform these actions on org admins or project admins
- Group admins cannot perform these actions on users outside their groups
Fixed
- Fixed inconsistency where SMS MFA could be disabled even when required by org policy
- Fixed issue where users could not remove a lost MFA device using a recovery code if MFA was required by org policy
v2.2.28 - 12/31/2025
Changed
- Security: Bumped Django to 4.2.27 to address GHSA-rqw2-ghq9-44m7 and GHSA-vrcr-9hj9-jcg6
- Security: Bumped urllib3 to 2.6.0 to address GHSA-gm62-xv2j-4w53 and GHSA-2xpw-w6gg-jr37
Fixed
- Critical Security Fix: Fixed global permissions object mutation bug in
/v2/account/access/current-sessionendpoint MIN_PROJECT_ACCESS_PERMISSIONSwas being mutated in place via the+=operator- When any project admin called the session endpoint, the global constant would become corrupted
- All subsequently created users would receive project admin privileges they shouldn't have
- Fixed by using
.copy()to create an independent copy before mutation - This prevented a silent cross-tenant privilege escalation vulnerability
v2.2.27 - 11/25/2025
Changed
- Security updates
v2.2.26 - 11/25/2025
Changed
- Security: Bumped Django to 4.2.25 to address GHSA-hpr9-3m2g-3j9p and GHSA-q95w-c7qg-hrff
Fixed
- Completing an SMS_MFA challenge now enables SMS MFA, sets preferred_mfa to SMS if unset, and marks phone_number_verified, so MFA enabled state displays correctly in the admin UI
- Fixed a mypy type issue in account picture upload by annotating PIL Image type
- MFA: After an incorrect MFA entry, Cognito can invalidate the session; our challenge endpoint now returns a clear 401 instructing clients to restart sign-in instead of retrying with the stale session
v2.2.25 - 09/12/2025
Added
- Added support for deployment to London Region (eu-west-2)
v2.2.24 - 07/22/2025
Changed
- Instantiate model tags as empty array ([]) without empty string
v2.2.23 - 07/22/2025
Fixed
- Fixed org admins not being able to force delete projects
v2.2.22 - 07/22/2025
Fixed
- Fixed org admins not being able to login to project due to duplicate users being returned from query
v2.2.21 - 07/03/2025
Fixed
- Fixed OWN_URL to be determined by environment
Changed
- Security updates
v2.2.20 - 07/03/2025
Changed
- Security updates
v2.2.19 - 06/18/2025
Added
- Added support for deployment to Sydney Region (ap-southeast-2)
v2.2.18 - 03/03/2025
Changed
- Remove inactive groups from account group access
- Add include_inactive_groups as param to account group access request
v2.2.17 - 02/24/2025
Fixed
- Fixed issue with users when MFA required can not proceed
Changed
- Security updates
v2.2.16 - 11/22/2024
Added
- Caching for authentication to improve throughput
v2.2.15 - 11/13/24
Added
- Improvements to debug logging capabilities
v2.2.14 - 11/11/24
Fixed
- Fixed issue preventing listing roles using roles permissions in some cases
v2.2.13 - 11/8/24
Changed
- Security updates
v2.2.12 - 10/29/24
Changed
- Security updates
v2.2.11 - 10/25/24
Changed
- Removed the uniqueness requirement for group name
v2.2.10 - 10/21/24
Added
- Support for org/project alias, for simpler login
- Alias is a new setting on all orgs and projects
- Client UI config endpoint now optionally accepts alias as the path parameter
- Client UI config endpoint will return client ID in the response
- This enables our dashboard login page to accept an alias on the first step
- Alias must be universally unique
Changed
- Security updates
v2.2.9 - 7/26/24
Added
/.well-known/security.txtpath with vulnerability disclosure information, per RFC 9116- Endpoints for listing access objects for a target role, one per resource type
- Query parameter
is_group_adminto be used when filtering by group ID
v2.2.8 - 6/27/24
Added
- Ability for staff to increase maximum number of roles per user in an organization
v2.2.7 - 6/19/24
Changed
- Can now modify project_permissions logged into org if the device or role is project-linked
- Security updates
v2.2.6 - 6/1/24
Fixed
- Resolved issue using roles to read groups in some cases
- Uncaught conflict error when creating existing group access
v2.2.5 - 5/28/24
Changed
- Security updates
v2.2.4 - 5/23/24
Fixed
- Resolved issue with some images not uploading to the account picture endpoint
v2.2.3 - 5/13/24
Added
- Propagating group name, description, and tags onto account group access schema
- Propagating project name, description, and tags onto account project access schema
- Propagating role name, description, and tags onto account role access schema
- Added query parameters for all the above on their respective account access endpoints
- New group setting to modify data permissions
- If
require_delete_permission_to_put_datais True, PUTting data requires delete + write - Enables assigning permission to POST data without being able to PUT data and possibly overwrite
- New org and project settings to optionally set any of the above group settings true by default
- New admin-only param
forcewill override delete protection - Group data and files permissions now support
can_updatefield for all new organizations by default - Org and project setting
use_legacy_data_and_files_permissionsis true for existing organizations - For new organizations, or if toggled false, PATCH uses
can_updatepermission instead ofcan_write - New projects default to the same value as their organization, but can be set independently
Changed
- Changed dashboard_config > widgets > list[] > config to more general dict type
v2.2.2 - 5/3/24
Fixed
- Unhandled validation of JSON value in new data entries
v2.2.1 - 4/29/24
Fixed
- Error reading/writing data with project admin priviledge
v2.2.0 - 4/26/24
Added
- Endpoints to upload/delete profile picture stored as picture_base64 on the user/device
- Supports JPEG or PNG, with content type stored on picture_content_type field
- Max size 10MB, large images will be resized so 256px is the largest dimension
- Minimum picture size is 24x24px
- CRUD interface for roles, which can be used to bundle permissions for users and devices
- CRUD interface for roles access
- Roles permissions now usable in all interfaces
- Can be granted access to resources in the same way you would a user or a device
- Unlike users and devices, roles cannot be granted access to other roles
- Unlike users and devices, regular read permission is enough to view access a role possesses
- Org/project admin status in tokens reflects admin privileges via roles as well
- Toggling off admin priviledge for a role will log out all users with access to that role
- Users/devices use permissions of their roles as their own
- Support for additional substitution variables in email templates
- org_name, org_id, project_name, project_id, username, first_name, last_name, nickname, datetime, date, time, zoneinfo
- Added endpoints to get/set a dashboard configuration for the current user
- Added endpoint to retrieve UI configuration for a given client ID
Changed
- Update and delete operations no longer require read permissions
- All bool query parameters that are provided with an empty value are treated as true
- Access objects now have IDs that are 29 characters long and begin with the target resource ID
v2.1.21 - 4/18/24
Added
- Fields
project_nameandproject_descriptionadded to project access objects - Fields
group_nameandgroup_descriptionadded to group access objects
Changed
- Minimum session validity raised to 3 minutes
- Fields
localeanddefault_localenow normalized before validation/storage
Fixed
- Uncaught error for invalid session length during software MFA setup
- Some permissions not getting through during group or project access creation
v2.1.20 - 4/10/24
Fixed
- Uncaught schema handling error for invalid set password request payloads
v2.1.19 - 4/4/24
Changed
- Default set password links now point to
app.cyphermed.cloudinstead ofcyphermed.cloud
v2.1.18 - 2/28/24
Added
- Field
has_temporary_passwordadded to user schema for admins
Changed
- If a user never set their first password, forgot password flow will re-send invite email
- Admin send recovery email endpoint supports template override for this case as well
- Org name must only contain letters, numbers, spaces, period, comma, underscore, or hyphen
v2.1.17 - 2/26/24
Changed
- Username and email are case-insensitive for login and user lookup
- ex. user with email
TEST@example.comcan now login withtest@example.com - Already case-insensitive at user creation/modification, so this change is backwards-compatible
v2.1.16 - 2/15/24
Added
- Optional template_id parameter for overriding recovery email as admin
- Track new password required state on the user model
- Track password and API key last changed datetimes
v2.1.15 - 2/13/24
Added
- Ability to filter data and file entries by created_by or last_updated_by
v2.1.14 - 2/12/24
Changed
- Minor schema cleanup
v2.1.13 - 2/8/24
Added
- Ability to filter database resources by created_by or last_updated_by
- Does not yet include data or file entries
v2.1.12 - 2/6/24
Changed
- Minor schema cleanup to address issue in SDK generation
v2.1.11 - 2/6/24
Changed
- All users and devices can update and deactivate themselves
- The project_ids, group_ids, and role_ids fields are omitted from the user schema, rather than set to null, for those without permission to view them
Fixed
- Permission can_read not providing read access to groups in some cases
v2.1.10 - 2/2/24
Fixed
- Fixed error on filtering by tags
- Fixed error on code mismatch during MFA setup
v2.1.9 - 1/30/24
Changed
- Default limit on all paginated interfaces is now 100, maximum is 1000
- Maximum lifetime of reset tokens increased to 1 week
Fixed
- Fixed missing last_evaluated_key on paginated responses
v2.2.0 - Unreleased
Added
- CRUD interface for roles
- Can manage org/project permissions directly on the role, same as users or devices
- CRUD interface for role access
- Role permissions now usable on all interfaces
Changed
- Update and delete operations no longer require read permissions
- Individual org-level resources can be managed at the project level
- Requires sufficient org-level permissions
- Org-level resources still do not show up in project-level resource lists
v2.1.8 - 12/8/23
Added
- Description field on orgs, projects, and groups
Changed
- A user's tokens will all be revoke when stripped of org or project admin status
- A user's tokens will all be revoke when removing MFA if required by org policy
- Functions add_sms/software_mfa have been renamed to enable_sms/software_mfa
- Functions remove_sms/software_mfa have been renamed to disable_sms/software_mfa
- Cannot disable software MFA when MFA it is required by org policy
- MFA session + recovery code can be used to setup SMS MFA
Fixed
- Updating org access no longer reverts fields to default if left unset
- Fixed challenge responses when removing MFA required by your org
v2.1.7 - 12/4/23
Changed
- Data/file paths and IoT scopes are now automatically prepended with a slash if missing
- Can no longer set is_active when creating group or project access
- The field is_active is only visible to admins
Fixed
- Fixed grantee lookup when creating new group or project access as an admin
- Fixed is_active not being respected for some permissions checks
- Fixed permissions checks on certain user and device list filters
v2.1.6 - 11/30/23
Changed
- Project login fields can now be a subset OR superset of the parent organization login fields
- When creating project access, reject if user has a conflicting login field
- When creating a user in a project, reject if user has a conflicting login field
- When updating a user, reject if it would break login for the org or any projects
Fixed
- Fixed SMS MFA setup flow using session token
- Fixed parameters for MFA select challenge response
v2.1.5 - 11/28/23
Added
- Bucket versioning enabled on new S3 buckets
- Noncurrent version expiration enabled on new S3 buckets
- Error email for internal server errors and service unavailable errors
Changed
- Limit the domains of staff emails
Fixed
- Fixed org deletion, and added more error handling
v2.1.4 - 11/22/23
Fixed
- Fixed creation of project-linked devices
v2.1.3 - 11/22/23
Added
- CRUD interface for managing projects
- CRUD interface for managing project access
Changed
- Username, device name, project names, and all other resource names are case insensitive
- Enable deletion protection on new DynamoDB tables, disable before org deletion
- Enable point-in-time recovery on new DynamoDB tables
- Apply HTTS-only policy to new S3 buckets
- Apply CORS policy to new S3 buckets
v2.1.2 - 11/22/23
Added
- Endpoint to reset API key for a device
- Endpoint to reset MQTT credentials for a device
- MQTT broker enabled for all devices
- New devices now get issued a certificate and public/private key pair at creation
#Changed
- Only admins can update
iot_scopeson devices - Only admins or current device owner can update a device's owner
v2.1.1 - 11/22/23
Added
- Endpoints to delete SMS or software MFA of another user as admin
- Endpoint to send or resend SMS verification code
- Added
preferred_mfa,sms_mfa_enabled, andsoftware_mfa_enabledto the user schema - Added
is_project_adminto user schema when in project scope
Changed
- Getting/deleting single data or file objects which are not found now returns 404 for consistency
- Include list of IDs for resources individual users or devices have access to
- Include org or project permissions on own user or device info
- Include org or project permissions on other individuals if you are an admin
- "Update" renamed to "Patch" in all schemas and endpoint names
- Adding SMS MFA no longer automatically sends a verification code
- SMS MFA recovery code now always returned when adding SMS MFA
- SMS MFA recovery code no longer returned by SMS verification endpoint
v2.1.0 - 11/22/23
Added
- Support for SMS multi-factor authentication
- Recovery codes for each MFA device type
- Endpoint for triggering account recovery for another user as admin
- Endpoints to remove another user's MFA as admin, one for each device type
- Added custom_attributes and restricted_custom_attributes JSON field on base model
- Only admins can update restricted_custom_attributes
- Support sort, search, and filter over custom attributes
- Currently only exposed/usable with users and devices, more coming soon
Changed
- Email template flag
for_forgot_passwordrenamed tofor_account_recovery - Renamed function
update_passwordtoset_password - Recovery template also used when admins trigger account recovery for another user
- Changed bulk data field name from
results_by_pathtodata_by_pathfor consistency - Datetime & unicode gt/le dot operators replaced with inclusive equivalent gte/lte
- Login form now additionally accepts email or phone number in the
usernamefield - Usernames are now case-insensitive
v2.0.2 - 11/15/23
Added
- Automated SDK release PR for every new API release
- Generate and backup CVE reports in HTML format for all PRs
Changed
- Improved default email templates
- Replaced HTTP 302 with HTTP 308 when using redirect param for file retrieval
- Data-oriented operations authenticated with an API key are slightly faster
Fixed
- eTag missing from file GET response
- Corrected file key in presigned GET URLs when using cascade parameter
- Incorrectly reporting resource conflict for some email template updates
v2.0.1 - 10/2/23
Added
- Optionally accept content-type for presigned PUT URLs
- Capture and store etag for file uploads
Changed
- Replaced HTTP 422 responses with the more common HTTP 406
Fixed
- Various schema validation fixes
- Clean up error message for invalid field type
- Fix some non-compliant OpenAPI spec output caused by gt/lt constraints
v2.0.0 - 9/18/23
Added
- OAuth2.0 user password credential + refresh token flow
- Software token multi-factor authentication
- Fully encrypted access control and data storage
- ECDH key exchange
- EdDSA digital signatures
- AES-GCM authenticated encryption
- Forgot password email flow
- Forgot password email trigger lambda function
- Account access interface, to list own access objects
- Billing points interface (staff only)
- My organization settings interface
- My project settings interface
- Data interface, for JSON document storage/search
- Devices interface, for device management
- Can utilize the managed MQTT broker in IoT Core
- Devices use API keys to authenticate
- Files interface, for searchable object storage
- Update files index lambda function
- Groups interface, to collect users/devices
- Organizations interface (staff only)
- Email templates interface
- Users interface
- Dockerfile for production deployment
- Initial project setup: test suite, linting, CI/CD pipeline, etc.