Secure Canvas API token persistence with AES-GCM and legacy token reset migration#676
Conversation
|
@copilot Can you add a short python script to the /docs/README_Canvas_API_Keys.md that will generate suitable values for CANVAS_API_TOKEN_ENCRYPTION_KEY? Can you also add a database migration that clears all current values of the Canvas API Token field, and document that in the /docs/README_Canvas_API_Keys.md in a section on "Migration" |
|
@copilot please look over the output of jacoco and pitest and add additional tests to cover the coverage gaps and surviving mutations |
Addressed in |
|
@copilot Can you add a database migration that sets all existing canvas tokens to null? The existing tokens will be in plaintext, so they should be removed and replaced with ones that are encrypted. |
Implemented in |
|
@copilot Please run mvn git-code-format:format-code to fix the problems with 15-backend-format. Then, please run mvn clean test jacoco:report, look at the report,and add tests to address the gaps in test coverage. |
Done in |
|
@copilot There are still an uncovered branches in CanvasApiTokenSecurityService.java on lines 87 and 96. Please write tests to be sure that all branches are covered on these lines. |
Implemented in |
…SecurityService.java
…lot/secure-canvas-api-keys
Canvas API keys were persisted in plaintext, creating unnecessary exposure risk for FERPA-sensitive integrations. This change encrypts tokens at rest, preserves plaintext interoperability at request boundaries, and adds a migration to clear legacy plaintext tokens from existing rows.
Encrypted token storage and retrieval
CanvasApiTokenSecurityServicefor versioned token encryption/decryption (enc:v1:) using AES-GCM.CANVAS_API_TOKEN_ENCRYPTION_KEY(app.canvas.api-token-encryption-key), with fail-closed behavior for invalid/missing key when encrypting.Controller write/read path hardening
CoursesController.postCourse(...)andupdateCourseWithCanvasToken(...)now encrypt incoming Canvas tokens before save.getCanvasInfo(...)decrypts before applying existing masking logic, so UX behavior stays consistent while storage is ciphertext.Canvas API call boundary handling
CanvasServicenow decrypts token only when constructing outboundAuthorizationheaders for Canvas GraphQL calls.Schema and configuration updates
COURSE.CANVAS_API_TOKENfromVARCHAR(255)toVARCHAR(1024)to accommodate encrypted payloads.COURSE.CANVAS_API_TOKENvalues toNULL, removing legacy plaintext tokens so replacements are stored encrypted via the new write path..env.SAMPLEandapplication.propertiesfor encryption key configuration.Security documentation for audit
/docs/README_Canvas_API_Keys.mddocumenting threat model focus, controls, key management expectations, backward compatibility, and operational guidance for security review.