ABDM Consent Manager Implementation Plan (Updated)
Overview
This document outlines the implementation plan for the ABDM Consent Manager (CM) module for patient-centric consent management. The implementation leverages existing HIU/HIP infrastructure without creating new database tables or fields, using ABDM APIs as the source of truth for configurations.
Current State Analysis
Existing Infrastructure
The following components are already implemented and working:
HIP (Healthcare Information Provider)
- Controllers:
HipConsentsController,HipConsentWebhooksController - Models:
HipConsent - Routes:
/consentsendpoints for HIP - Webhook handlers for consent notifications
HIU (Healthcare Information User)
- Controllers:
HiuConsentRequestsController,HiuConsentWebhooksController - Models:
HiuConsentRequest,HiuConsentArtefact - Services:
HiuConsentRequestServices::Init,HiuConsentRequestServices::OnNotifyHiu - Interactors:
HiuConsentRequestActions::Create,Index,Show - Routes:
/consent_requestsendpoints for HIU - Webhook handlers managing consent status updates
Supporting Infrastructure
AbdmRequest: Logs all ABDM API callsAbdmWebhook: Logs all webhook dataAbdm::FetchGatewayTokenV3: Token management- PHR Login: Patient authentication system
What's Being Added
The Consent Manager (CM) module adds patient-facing capabilities:
- Auto-approval configuration via ABDM APIs
- Direct consent request management by patients
- Consent approval/denial by patients
- Consent revocation functionality
- Enhanced consent artefact management
Architecture Approach
Core Principles
- No new database tables - Use existing HiuConsentRequest and HiuConsentArtefact models
- Leverage webhooks - Existing webhook handlers already manage consent data flow
- ABDM as source of truth - Store configurations in ABDM, fetch via API when needed
- Follow existing patterns - Use established interactor/service/controller patterns
High-Level Flow
Consent Management Flow
- Auto-Approval Configuration: Patients configure auto-approval via ABDM API
- Consent Request Listing: Fetch from ABDM CM API, sync with HiuConsentRequest
- Consent Approval/Denial: Patient actions via ABDM CM API
- Consent Revocation: Revoke via ABDM API, webhook updates status
- Consent Artefact Management: View and manage via ABDM APIs
Integration Points
- Uses existing
clinic_patientsfor patient identification - Leverages existing ABDM token management (
Abdm::FetchGatewayTokenV3) - Follows AbdmRequest logging pattern for all external API calls
- Integrates with existing HIU consent request flow via webhooks
Implementation Components
No Database Changes Required
This implementation uses existing database infrastructure:
- HiuConsentRequest: Already stores consent requests with status
- HiuConsentArtefact: Already stores consent artefacts
- AbdmRequest: Logs all API calls to ABDM
- AbdmWebhook: Logs all webhook data
Auto-approval configurations are stored in ABDM and fetched via API when needed.
Service Layer Implementation
Directory Structure
parts/abdm/services/abdm/cm/
├── cm_auto_approval_services/
│ ├── create.rb # POST /api/hiecm/consent/v3/auto/approve
│ ├── fetch.rb # GET auto-approval configuration from ABDM
│ ├── enable.rb # POST /api/hiecm/consent/v3/auto/approve/{id}/enable
│ └── disable.rb # POST /api/hiecm/consent/v3/auto/approve/{id}/disable
├── cm_consent_services/
│ ├── fetch_all.rb # GET /api/hiecm/consent/v3/request
│ ├── fetch_details.rb # GET /api/hiecm/consent/v3/request/{id}
│ ├── approve.rb # POST /api/hiecm/consent/v3/request/{id}/approve
│ ├── deny.rb # POST /api/hiecm/consent/v3/request/{id}/deny
│ └── revoke.rb # POST /api/hiecm/consent/v3/revoke
└── cm_artefact_services/
├── fetch_all.rb # GET /api/hiecm/consent/v3/artefact
├── fetch_by_id.rb # GET /api/hiecm/consent/v3/artefact/{id}
└── fetch_by_request.rb # GET /api/hiecm/consent/v3/artefact/request/{requestId}Service Implementation Pattern
module Abdm
module Cm
module CmConsentServices
class Approve
def self.perform(consent_request_id, consent_data, clinic_patient_id)
# 1. Get authentication token
token = Abdm::FetchGatewayTokenV3.perform
# 2. Build API request
url = "#{Rails.application.credentials.abdm_gateway_host_cm}/api/hiecm/consent/v3/request/#{consent_request_id}/approve"
headers = build_headers(token)
body = build_request_body(consent_data)
# 3. Make API call
begin
result = HTTParty.post(url, body: body.to_json, headers: headers)
rescue StandardError => e
error = e.to_s
end
# 4. Log in AbdmRequest
abdm_request = log_request(url, body, clinic_patient_id)
# 5. Handle Response
handle_response(result, error, abdm_request)
end
private
def self.build_headers(token)
{
'Content-Type' => 'application/json',
'Authorization' => "Bearer #{token}",
'X-CM-ID' => Rails.application.credentials.abdm_cm_id,
'X-AUTH-TOKEN' => "Bearer #{token}",
'REQUEST-ID' => SecureRandom.uuid,
'TIMESTAMP' => Time.now.utc.iso8601(3)
}
end
def self.build_request_body(consent_data)
{
consents: consent_data[:consents]
}
end
def self.log_request(url, body, clinic_patient_id)
AbdmRequest.create!(
request_id: SecureRandom.uuid,
url: url,
payload: body,
requested_by_id: clinic_patient_id,
requested_by_type: 'ClinicPatient'
)
end
def self.handle_response(result, error, abdm_request)
if result.present? && result.success?
success = true
response = result.parsed_response
code = result.code
elsif error.present?
success = false
response = { error: error }
else
success = false
response = result.parsed_response
code = result.code
end
abdm_request.update!(
response: response,
status_code: code,
success: success
)
{ success: success, data: response }
end
end
end
end
endInteractor Layer Implementation
Directory Structure
parts/abdm/interactors/abdm/cm/
├── cm_auto_approval_actions/
│ ├── create.rb # Create auto-approval configuration
│ ├── fetch.rb # Get current configuration
│ ├── enable.rb # Enable auto-approval for HIU
│ └── disable.rb # Disable auto-approval for HIU
├── cm_consent_actions/
│ ├── index.rb # List all consent requests (with filters)
│ ├── show.rb # Show specific consent request details
│ ├── approve.rb # Approve consent request
│ ├── deny.rb # Deny consent request with reason
│ ├── pending.rb # Get pending consent requests
│ ├── approved.rb # Get approved consent requests
│ └── denied.rb # Get denied consent requests
└── cm_artefact_actions/
├── index.rb # List all consent artefacts
├── show.rb # Show specific artefact details
├── revoke.rb # Revoke consent artefact
└── by_request.rb # Get artefacts by request IDInteractor Implementation Pattern
module Abdm
module Cm
module CmConsentActions
class Approve < BaseInteractor
def call
require_context(:consent_request_id)
require_context(:clinic_patient_id)
require_context(:consents)
validate_patient!
fetch_consent_from_abdm!
prepare_consent_data!
# Call ABDM CM API to approve
result = Abdm::Cm::CmConsentServices::Approve.perform(
context.consent_request_id,
context.consent_data,
context.clinic_patient_id
)
fail_with_error!('Approval failed', result[:error]) unless result[:success]
# Webhook will update HiuConsentRequest status
context.records = result[:data]
context.message = 'Consent request approved successfully'
end
private
def validate_patient!
context.clinic_patient = ClinicPatient.find_by(id: context.clinic_patient_id)
fail_with_error!('Patient not found') unless context.clinic_patient
end
def fetch_consent_from_abdm!
# Fetch consent details from ABDM CM API
result = Abdm::Cm::CmConsentServices::FetchDetails.perform(
context.consent_request_id,
context.clinic_patient_id
)
fail_with_error!('Cannot fetch consent details') unless result[:success]
context.consent_details = result[:data]
end
def prepare_consent_data!
context.consent_data = {
consents: context.consents.map do |consent|
{
hiTypes: consent[:hi_types],
hip: { id: consent[:hip_id] },
careContexts: consent[:care_contexts],
permission: {
dateRange: {
from: consent[:date_from],
to: consent[:date_to]
},
frequency: consent[:frequency] || { unit: 'DAY', value: 0, repeats: 0 },
accessMode: consent[:access_mode] || 'VIEW',
dataEraseAt: consent[:data_erase_at]
}
}
end
}
end
end
end
end
endController Layer Implementation
Controller Structure
# parts/abdm/controllers/abdm/cm/cm_auto_approvals_controller.rb
module Abdm
module Cm
class CmAutoApprovalsController < ApiController
before_action :policy_check
def create # POST - Create auto-approval config
result = Cm::CmAutoApprovalActions::Create.call(params)
render_result(result)
end
def show # GET - Get current config
result = Cm::CmAutoApprovalActions::Fetch.call(params)
render_result(result)
end
def enable # POST - Enable auto-approval
result = Cm::CmAutoApprovalActions::Enable.call(params)
render_result(result)
end
def disable # POST - Disable auto-approval
result = Cm::CmAutoApprovalActions::Disable.call(params)
render_result(result)
end
private
def policy_check
authorize params, policy_class: CmAutoApprovalsControllerPolicy
end
end
end
end
# parts/abdm/controllers/abdm/cm/cm_consents_controller.rb
module Abdm
module Cm
class CmConsentsController < ApiController
before_action :policy_check
def index # GET - List consent requests
result = Cm::CmConsentActions::Index.call(params)
render_result(result)
end
def show # GET - Show consent details
result = Cm::CmConsentActions::Show.call(params)
render_result(result)
end
def approve # POST - Approve consent
result = Cm::CmConsentActions::Approve.call(params)
render_result(result)
end
def deny # POST - Deny consent
result = Cm::CmConsentActions::Deny.call(params)
render_result(result)
end
def pending # GET - Filter pending
result = Cm::CmConsentActions::Pending.call(params)
render_result(result)
end
def approved # GET - Filter approved
result = Cm::CmConsentActions::Approved.call(params)
render_result(result)
end
def denied # GET - Filter denied
result = Cm::CmConsentActions::Denied.call(params)
render_result(result)
end
private
def policy_check
authorize params, policy_class: CmConsentsControllerPolicy
end
end
end
endRoutes Configuration
# In parts/abdm/routes.rb, add under the abdm namespace:
namespace :cm do
# Auto-approval management
resource :auto_approval, only: [:create, :show], controller: 'cm_auto_approvals' do
post :enable
post :disable
end
# Consent management
resources :consents, only: [:index, :show], controller: 'cm_consents' do
member do
post :approve
post :deny
end
collection do
get :pending
get :approved
get :denied
end
end
# Artefact management
resources :consent_artefacts, only: [:index, :show], controller: 'cm_consent_artefacts' do
member do
post :revoke
end
collection do
get 'request/:request_id', action: :by_request
end
end
end
# Webhook routes (if needed)
match '/abdm/cm/on-auto-approval', to: 'abdm/cm/cm_webhooks#on_auto_approval', via: [:post]API Headers Configuration
All CM API calls require the following headers:
{
'Content-Type' => 'application/json',
'Authorization' => "Bearer #{token}", # From Abdm::FetchGatewayTokenV3
'X-CM-ID' => Rails.application.credentials.abdm_cm_id,
'X-AUTH-TOKEN' => "Bearer #{token}",
'REQUEST-ID' => SecureRandom.uuid,
'TIMESTAMP' => Time.now.utc.iso8601(3)
}Data Flow
Auto-Approval Configuration Flow
- Patient configures auto-approval → API call to ABDM
- Configuration stored in ABDM (not local DB)
- When consent request arrives → ABDM checks auto-approval
- Auto-approved requests → webhook updates HiuConsentRequest status
Consent Request Management Flow
- Fetch consent requests from ABDM CM API
- Sync with existing HiuConsentRequest records
- Display combined data to patient
- Patient approves/denies → API call to ABDM
- Webhook updates local HiuConsentRequest status
Consent Revocation Flow
- Patient selects consent to revoke
- API call to ABDM with consent IDs
- ABDM processes revocation
- Webhook updates HiuConsentArtefact status
Implementation Phases
Phase 1: Foundation (Week 1)
- Create directory structure for CM module
- Implement fetch services (read-only operations)
- Create basic controllers and routes
- Test with existing HIU consent data
Phase 2: Auto-Approval (Week 1-2)
- Implement auto-approval create service
- Add enable/disable functionality
- Create corresponding interactors
- Integration testing with ABDM sandbox
Phase 3: Consent Management (Week 2-3)
- Implement approve/deny services
- Add consent filtering (pending/approved/denied)
- Create patient-facing API endpoints
- Handle error scenarios
Phase 4: Revocation & Artefacts (Week 3)
- Implement revoke service
- Add artefact fetch functionality
- Complete webhook integration
- End-to-end testing
Phase 5: Testing & Documentation (Week 4)
- Unit tests for all services
- Integration tests with ABDM sandbox
- API documentation
- Error handling improvements
Key Implementation Notes
- No Database Changes: All consent data uses existing HIU tables
- ABDM as Source: Auto-approval config stored in ABDM, not locally
- Webhook Integration: Existing webhook handlers update local records
- Authentication: Use existing PHR login for patient authentication
- Error Handling: Follow existing BaseInteractor error patterns
- Logging: All API calls logged in AbdmRequest table
API Endpoints Summary
Auto-Approval
POST /api/v3/abdm/cm/auto_approval- Configure auto-approvalGET /api/v3/abdm/cm/auto_approval- Get configurationPOST /api/v3/abdm/cm/auto_approval/enable- EnablePOST /api/v3/abdm/cm/auto_approval/disable- Disable
Consent Management
GET /api/v3/abdm/cm/consents- List all consentsGET /api/v3/abdm/cm/consents/:id- Get consent detailsPOST /api/v3/abdm/cm/consents/:id/approve- ApprovePOST /api/v3/abdm/cm/consents/:id/deny- DenyGET /api/v3/abdm/cm/consents/pending- Pending consentsGET /api/v3/abdm/cm/consents/approved- Approved consentsGET /api/v3/abdm/cm/consents/denied- Denied consents
Consent Artefacts
GET /api/v3/abdm/cm/consent_artefacts- List artefactsGET /api/v3/abdm/cm/consent_artefacts/:id- Get artefactPOST /api/v3/abdm/cm/consent_artefacts/:id/revoke- RevokeGET /api/v3/abdm/cm/consent_artefacts/request/:request_id- By request
Success Metrics
- API response time < 2 seconds
- Successful ABDM integration
- No database migrations required
- Seamless integration with existing HIU/HIP modules
- All consent operations functional