TL;DR (요약)
API를 위한 HIPAA 규정 준수는 전송 중 및 저장 시 암호화, 감사 로깅, 접근 제어, 사업 제휴 계약 등을 포함하여 PHI(개인 건강 정보)에 대한 엄격한 보안 제어를 구현해야 합니다. 이 가이드는 PHI를 처리하는 헬스케어 애플리케이션을 위한 API 아키텍처 패턴, 인증 요구 사항, 감사 추적 구현 및 규정 준수 검증을 다룹니다.
서론
헬스케어 데이터 유출 사고는 건당 평균 1,093만 달러의 비용을 초래합니다. 헬스케어 애플리케이션을 개발하는 개발자에게 API 보안은 선택 사항이 아니라, HIPAA(Health Insurance Portability and Accountability Act)에 따른 법적 요구 사항입니다.
현실은 다음과 같습니다: 헬스케어 데이터 유출의 79%는 API 및 애플리케이션 취약점을 통한 무단 접근과 관련이 있습니다. 적절하게 설계된 HIPAA 준수 API 아키텍처는 유출을 방지하고, 감사 추적을 가능하게 하며, 환자 프라이버시를 보호합니다.
이 가이드는 HIPAA API 규정 준수 프로세스 전체를 안내합니다. PHI 처리 요구 사항, 암호화 표준, 접근 제어 구현, 감사 로깅 및 규정 준수 문서를 배우게 됩니다. 이 가이드의 끝에 도달하면 프로덕션 환경에 바로 적용할 수 있는 HIPAA 준수 API 아키텍처를 갖추게 될 것입니다.
HIPAA란 무엇이며 API에 왜 중요한가요?
HIPAA는 민감한 환자 건강 정보를 보호하기 위한 국가 표준을 수립하는 연방법입니다. HIPAA 보안 규칙은 특히 API를 통해 전송되는 전자 보호 건강 정보(ePHI)를 다룹니다.
규정 준수 대상
| 주체 유형 | 예시 | API 관련 사항 |
|---|---|---|
| 적용 대상 기관 | 헬스케어 제공자, 건강 보험, 청구서 교환소 | 직접적인 HIPAA 책임 |
| 사업 제휴 기관 | API 제공자, 클라우드 서비스, 소프트웨어 공급업체 | BAA 필요, 직접적인 책임 |
| 하도급업체 | 하위 처리자, 다운스트림 API 서비스 | BAA 필요 |
API를 위한 주요 HIPAA 규칙
개인 정보 보호 규칙: PHI의 사용 및 공개를 규율
- 최소 필요 표준
- 환자 접근 권한
- 승인 요구 사항
보안 규칙: ePHI를 위한 기술적 보호 장치
- 접근 제어
- 감사 제어
- 무결성 제어
- 전송 보안
유출 통지 규칙: 사건 대응 요구 사항
- 60일 통지 기간
- 위험 평가 문서화
- 완화 절차
API 아키텍처 개요
HIPAA 준수 API 아키텍처에는 다음이 포함됩니다:
┌─────────────────────────────────────────────────────────────────┐
│ HIPAA-COMPLIANT API STACK │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ CLIENT │───▶│ API │───▶│ DATABASE │ │
│ │ (앱) │ │ Gateway │ │ (암호화됨) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ OAuth 2.0 │ │ WAF + │ │ Audit │ │
│ │ + MFA │ │ Rate Limit│ │ Logging │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ 모든 데이터 암호화됨: 전송 중 TLS 1.3+, 저장 시 AES-256 │
│ │
└─────────────────────────────────────────────────────────────────┘
시작하기: 규정 준수 기반
1단계: 사업 제휴 계약(BAA) 체결
PHI를 처리하기 전에:
- PHI 접근 권한이 있는 모든 공급업체 식별
- 각 공급업체와 BAA 체결
- BAA에 하위 처리자 문서화
- 매년 검토하고 필요에 따라 업데이트
BAA가 필요한 주요 공급업체:
- 클라우드 호스팅 (AWS, GCP, Azure)
- 데이터베이스 제공업체
- 로깅 서비스
- 백업 제공업체
- API 게이트웨이
- 모니터링 도구
BAA 없이 사용해서는 안 되는 것들:
- 일반 Google Analytics
- 무료 티어 클라우드 서비스
- 개인 이메일 계정
- 비 헬스케어 Slack 채널
2단계: 데이터 분류
API가 처리하는 모든 데이터 분류:
| 데이터 유형 | 분류 | 보호 수준 |
|---|---|---|
| 환자 이름 + 생년월일 | PHI | 전체 HIPAA 제어 |
| 의무 기록 번호 | PHI | 전체 HIPAA 제어 |
| 진단 코드 (ICD-10) | PHI | 전체 HIPAA 제어 |
| 진료 기록 | PHI | 전체 HIPAA 제어 |
| 예약 시간 (환자 ID 없음) | PHI 아님 | 표준 제어 |
| 집계된, 비식별 데이터 | PHI 아님 | 표준 제어 |
3단계: 최소 필요 표준
API는 최소한의 필요한 데이터만 노출해야 합니다:
// 나쁨: 모든 환자 데이터를 반환
app.get('/api/patients/:id', async (req, res) => {
const patient = await db.patients.findById(req.params.id);
res.json(patient); // 모든 것을 반환
});
// 좋음: 필드 수준 필터링
app.get('/api/patients/:id', async (req, res) => {
const fields = req.query.fields?.split(',') || ['id', 'name'];
const allowedFields = ['id', 'name', 'dateOfBirth']; // 허용 목록
const patient = await db.patients.findById(req.params.id);
const filtered = Object.fromEntries(
Object.entries(patient).filter(([key]) => allowedFields.includes(key))
);
res.json(filtered);
});
기술적 보호 장치 구현
접근 제어: 인증
강력한 인증 구현:
const crypto = require('crypto');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');
// 다단계 인증 필요
class HIPAAAuthService {
async authenticate(username, password, mfaCode) {
// 1. 자격 증명 확인
const user = await this.getUserByUsername(username);
if (!user) throw new Error('Invalid credentials');
const validPassword = await bcrypt.compare(password, user.passwordHash);
if (!validPassword) throw new Error('Invalid credentials');
// 2. MFA(TOTP) 확인
const validMFA = this.verifyTOTP(user.mfaSecret, mfaCode);
if (!validMFA) throw new Error('Invalid MFA code');
// 3. 단기 JWT 생성 (PHI 접근 시 최대 15분)
const token = jwt.sign(
{
sub: user.id,
role: user.role,
mfa_verified: true
},
process.env.JWT_SECRET,
{ expiresIn: '15m' }
);
// 4. 인증 시도 로깅
await this.auditLog('AUTH_SUCCESS', { userId: user.id, ip: req.ip });
return { token, expiresIn: 900 };
}
verifyTOTP(secret, token) {
const period = 30;
const digits = 6;
const now = Math.floor(Date.now() / 1000);
const counter = Math.floor(now / period);
const buffer = Buffer.alloc(8);
buffer.writeUInt32BE(0, 0);
buffer.writeUInt32BE(counter, 4);
const hmac = crypto.createHmac('sha1', secret).update(buffer).digest();
const offset = hmac[hmac.length - 1] & 0xf;
const code = (
((hmac[offset] & 0x7f) << 24) |
((hmac[offset + 1] & 0xff) << 16) |
((hmac[offset + 2] & 0xff) << 8) |
(hmac[offset + 3] & 0xff)
) % Math.pow(10, digits);
return code.toString().padStart(digits, '0') === token;
}
}
접근 제어: 권한 부여
역할 기반 접근 제어(RBAC) 구현:
// 역할 정의
const ROLES = {
ADMIN: 'admin',
PROVIDER: 'provider',
NURSE: 'nurse',
BILLING: 'billing',
PATIENT: 'patient'
};
// 권한 매트릭스
const PERMISSIONS = {
[ROLES.ADMIN]: ['read:all', 'write:all', 'delete:all'],
[ROLES.PROVIDER]: ['read:patients', 'write:patients', 'read:labs', 'write:orders'],
[ROLES.NURSE]: ['read:patients', 'write:vitals', 'read:labs'],
[ROLES.BILLING]: ['read:billing', 'read:patients:limited'],
[ROLES.PATIENT]: ['read:self', 'write:self']
};
// 권한 부여 미들웨어
const authorize = (...requiredPermissions) => {
return async (req, res, next) => {
const user = req.user; // JWT 미들웨어로부터
const userPermissions = PERMISSIONS[user.role] || [];
const hasPermission = requiredPermissions.every(
perm => userPermissions.includes(perm)
);
if (!hasPermission) {
await auditLog('AUTHZ_DENIED', {
userId: user.id,
action: req.method,
path: req.path,
required: requiredPermissions
});
return res.status(403).json({ error: 'Insufficient permissions' });
}
next();
};
};
// 사용법
app.get('/api/patients/:id/records',
authenticate,
authorize('read:patients'),
getPatientRecords
);
전송 중 암호화
모든 API 통신에 TLS 1.3 강제 적용:
const https = require('https');
const fs = require('fs');
// 서버 설정
const options = {
key: fs.readFileSync('server-key.pem'),
cert: fs.readFileSync('server-cert.pem'),
ca: fs.readFileSync('ca-cert.pem'),
minVersion: 'TLSv1.3',
ciphers: [
'TLS_AES_256_GCM_SHA384',
'TLS_CHACHA20_POLY1305_SHA256',
'TLS_AES_128_GCM_SHA256'
].join(':'),
honorCipherOrder: true
};
const server = https.createServer(options, app);
// HTTPS 리디렉션 강제
app.use((req, res, next) => {
if (!req.secure) {
return res.redirect(`https://${req.headers.host}${req.url}`);
}
next();
});
// HSTS 헤더
app.use((req, res, next) => {
res.setHeader(
'Strict-Transport-Security',
'max-age=31536000; includeSubDomains; preload'
);
next();
});
저장 시 암호화
저장된 모든 PHI 암호화:
const crypto = require('crypto');
class EncryptionService {
constructor(key) {
// 키 관리를 위해 AWS KMS, GCP KMS 또는 Azure Key Vault 사용
this.key = crypto.scryptSync(key, 'salt', 32);
this.algorithm = 'aes-256-gcm';
}
encrypt(plaintext) {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(this.algorithm, this.key, iv);
let encrypted = cipher.update(plaintext, 'utf8', 'hex');
encrypted += cipher.final('hex');
const authTag = cipher.getAuthTag().toString('hex');
return {
encryptedData: encrypted,
iv: iv.toString('hex'),
authTag: authTag
};
}
decrypt(encryptedData, iv, authTag) {
const decipher = crypto.createDecipheriv(
this.algorithm,
this.key,
Buffer.from(iv, 'hex')
);
decipher.setAuthTag(Buffer.from(authTag, 'hex'));
let decrypted = decipher.update(encryptedData, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
}
// 암호화가 적용된 데이터베이스 모델
class PatientRecord {
constructor(db, encryptionService) {
this.db = db;
this.encryption = encryptionService;
}
async create(data) {
// 저장 전에 PHI 필드 암호화
const encryptedData = {
...data,
ssn: this.encryption.encrypt(data.ssn),
diagnosis: this.encryption.encrypt(data.diagnosis),
treatmentNotes: this.encryption.encrypt(data.treatmentNotes)
};
await this.db.patients.insert(encryptedData);
await auditLog('PHI_CREATED', { recordType: 'patient' });
}
async findById(id) {
const record = await this.db.patients.findById(id);
// 읽을 때 복호화
return {
...record,
ssn: this.encryption.decrypt(record.ssn.encryptedData, record.ssn.iv, record.ssn.authTag),
diagnosis: this.encryption.decrypt(record.diagnosis.encryptedData, record.diagnosis.iv, record.diagnosis.authTag),
treatmentNotes: this.encryption.decrypt(record.treatmentNotes.encryptedData, record.treatmentNotes.iv, record.treatmentNotes.authTag)
};
}
}
감사 제어 구현
포괄적인 감사 로깅
PHI에 대한 모든 접근 로깅:
const winston = require('winston');
// 변경 불가능한 감사 로거
const auditLogger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
// 추가 전용 저장소에 쓰기
new winston.transports.File({
filename: '/var/log/hipaa-audit/audit.log',
maxsize: 52428800, // 50MB
maxFiles: 365
}),
// SIEM에도 전송
new winston.transports.Http({
host: 'siem.internal',
path: '/api/logs',
ssl: true
})
]
});
// 감사 로깅 미들웨어
const auditLog = async (event, details) => {
const logEntry = {
timestamp: new Date().toISOString(),
event: event,
actor: details.userId,
action: details.action,
resource: details.resource,
outcome: details.outcome || 'SUCCESS',
ipAddress: details.ip,
userAgent: details.userAgent,
details: details.metadata
};
auditLogger.info(logEntry);
// 쿼리를 위해 데이터베이스에도 저장
await db.auditLogs.insert(logEntry);
};
// 자동 감사 미들웨어
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', async () => {
const duration = Date.now() - start;
// 모든 PHI 접근 로깅
if (req.path.includes('/patients') || req.path.includes('/records')) {
await auditLog('API_ACCESS', {
userId: req.user?.id || 'anonymous',
action: req.method,
resource: req.path,
outcome: res.statusCode < 400 ? 'SUCCESS' : 'FAILURE',
ip: req.ip,
userAgent: req.headers['user-agent'],
metadata: {
duration: duration,
statusCode: res.statusCode,
queryParams: Object.keys(req.query)
}
});
}
});
next();
});
필수 감사 이벤트
| 이벤트 유형 | 로깅할 내용 | 보존 기간 |
|---|---|---|
| 인증 | 성공/실패, MFA 상태, IP | 6년 |
| 권한 부여 | 거부된 접근 시도 | 6년 |
| PHI 접근 | 누가 무엇을 언제 접근했는지 | 6년 |
| PHI 수정 | 이전/이후 값 | 6년 |
| PHI 삭제 | 무엇이 누구에 의해 삭제되었는지 | 6년 |
| 시스템 변경 | 구성 변경, 새 사용자 | 6년 |
| 보안 이벤트 | 실패한 요청, 속도 제한 | 6년 |
감사 보고서 생성
규정 준수 보고서 생성:
const generateAuditReport = async (startDate, endDate, options = {}) => {
const query = {
timestamp: {
$gte: new Date(startDate),
$lte: new Date(endDate)
}
};
if (options.userId) {
query.actor = options.userId;
}
if (options.eventType) {
query.event = options.eventType;
}
const logs = await db.auditLogs.find(query).sort({ timestamp: 1 });
return {
reportPeriod: { start: startDate, end: endDate },
generatedAt: new Date().toISOString(),
summary: {
totalEvents: logs.length,
uniqueUsers: new Set(logs.map(l => l.actor)).size,
failures: logs.filter(l => l.outcome === 'FAILURE').length,
phiAccess: logs.filter(l => l.event === 'PHI_ACCESS').length
},
events: logs
};
};
// 주간 보고서 예약
cron.schedule('0 0 * * 1', async () => {
const end = new Date();
const start = new Date(end.getTime() - 7 * 24 * 60 * 60 * 1000);
const report = await generateAuditReport(start, end);
await sendToComplianceTeam(report);
});
API 보안 모범 사례
입력 유효성 검사
인젝션 공격 방지:
const { body, param, query, validationResult } = require('express-validator');
// 모든 입력에 대한 엄격한 유효성 검사
const validatePatientRequest = [
body('firstName')
.trim()
.notEmpty()
.matches(/^[a-zA-Z\s'-]+$/)
.withMessage('Invalid first name format')
.isLength({ max: 50 }),
body('dateOfBirth')
.isISO8601()
.withMessage('Invalid date format')
.custom(value => new Date(value) < new Date())
.withMessage('Date of birth must be in the past'),
body('ssn')
.optional()
.matches(/^\d{3}-\d{2}-\d{4}$/)
.withMessage('Invalid SSN format'),
body('email')
.optional()
.isEmail()
.normalizeEmail(),
param('id')
.isUUID()
.withMessage('Invalid patient ID format'),
(req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
error: 'Validation failed',
details: errors.array()
});
}
next();
}
];
속도 제한
남용 및 무차별 대입 공격 방지:
const rateLimit = require('express-rate-limit');
// 인증 엔드포인트에 대한 엄격한 제한
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15분
max: 5, // 창당 5회 시도
message: { error: 'Too many authentication attempts' },
standardHeaders: true,
legacyHeaders: false,
handler: async (req, res) => {
await auditLog('RATE_LIMIT_EXCEEDED', {
userId: req.body.username,
ip: req.ip,
endpoint: 'auth'
});
res.status(429).json({ error: 'Too many attempts' });
}
});
// 일반 API 제한
const apiLimiter = rateLimit({
windowMs: 60 * 1000, // 1분
max: 100, // 분당 100개 요청
message: { error: 'Rate limit exceeded' }
});
app.use('/api/auth', authLimiter);
app.use('/api', apiLimiter);
오류 처리
정보 유출 방지:
// 일반적인 오류 응답
app.use((err, req, res, next) => {
// 내부적으로 전체 오류 로깅
console.error('Error:', {
message: err.message,
stack: err.stack,
path: req.path,
user: req.user?.id
});
// 클라이언트에 대한 일반적인 응답
res.status(err.status || 500).json({
error: 'An error occurred processing your request',
requestId: req.id
});
});
// 오류 메시지에 노출해서는 안 되는 것:
// - 스택 추적
// - 데이터베이스 스키마
// - 내부 IP
// - 사용자 수
// - 오류 메시지의 PHI
일반적인 HIPAA API 위반 및 방지 방법
위반: 부적절한 접근 제어
시나리오: API가 인증된 모든 사용자가 모든 환자 기록에 접근하도록 허용합니다.
해결책: 적절한 권한 부여 검사 구현:
// 나쁨: 권한 부여 검사 없음
app.get('/api/patients/:id', async (req, res) => {
const patient = await db.patients.findById(req.params.id);
res.json(patient);
});
// 좋음: 사용자와 환자 간의 관계 확인
app.get('/api/patients/:id', async (req, res) => {
const patient = await db.patients.findById(req.params.id);
// 사용자가 환자인지 확인
if (req.user.id === patient.userId) {
return res.json(patient);
}
// 사용자가 할당된 제공자인지 확인
const assignment = await db.providerAssignments.findOne({
providerId: req.user.id,
patientId: patient.id
});
if (assignment) {
return res.json(patient);
}
await auditLog('UNAUTHORIZED_ACCESS_ATTEMPT', {
userId: req.user.id,
patientId: patient.id
});
res.status(403).json({ error: 'Access denied' });
});
위반: 누락된 감사 로그
시나리오: 누가 환자 데이터에 접근했는지 기록이 없습니다.
해결책: 위 감사 제어 섹션에 표시된 대로 모든 PHI 접근을 로깅합니다.
위반: 암호화되지 않은 데이터 전송
시나리오: API가 HTTP 연결을 허용합니다.
해결책: HSTS를 사용하여 HTTPS를 강제 적용합니다:
app.use((req, res, next) => {
if (!req.secure && process.env.NODE_ENV === 'production') {
return res.status(403).json({
error: 'HTTPS required. Connect via https://' + req.headers.host
});
}
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
next();
});
위반: 과도한 데이터 노출
시나리오: 이름만 필요한 경우에도 API가 전체 환자 기록을 반환합니다.
해결책: 필드 수준 필터링 구현:
app.get('/api/patients/:id', async (req, res) => {
const fields = req.query.fields?.split(',') || ['id', 'name'];
const projection = Object.fromEntries(fields.map(f => [f, 1]));
const patient = await db.patients.findById(req.params.id, projection);
res.json(patient);
});
프로덕션 배포 체크리스트
실시간 PHI를 처리하기 전에:
- [ ] 모든 공급업체와 BAA 체결
- [ ] 모든 사용자에 대해 MFA 구현
- [ ] 모든 엔드포인트에 TLS 1.3 활성화
- [ ] 모든 PHI를 저장 시 암호화 (AES-256)
- [ ] 포괄적인 감사 로깅 구현
- [ ] 로그 보존 설정 (6년 이상)
- [ ] 접근 제어 (RBAC) 구성
- [ ] 속도 제한 구현
- [ ] 사고 대응 계획 수립
- [ ] 모든 보안 제어 문서화
- [ ] 보안 위험 평가 수행
- [ ] HIPAA 요구 사항에 대해 직원 교육
- [ ] 정기 보안 감사 일정 수립
보안 위험 평가 템플릿
## HIPAA 보안 위험 평가
### 시스템 개요
- 시스템 이름: [API 이름]
- 처리되는 PHI 유형: [목록]
- 데이터 흐름: [다이어그램]
### 위협 평가
| 위협 | 가능성 | 영향 | 완화 |
|--------|------------|--------|------------|
| 무단 접근 | 중간 | 높음 | MFA, RBAC |
| 데이터 유출 | 낮음 | 치명적 | 암호화 |
| 내부자 위협 | 중간 | 높음 | 감사 로그 |
### 제어 테스트
- [ ] 인증 우회 테스트
- [ ] 권한 부여 우회 테스트
- [ ] SQL 인젝션 테스트
- [ ] XSS 테스트
- [ ] 암호화 검증
### 승인
보안 책임자: _______________ 날짜: _______
CTO: _______________ 날짜: _______
실제 사용 사례
원격 의료 플랫폼 API
원격 의료 스타트업이 HIPAA 준수 화상 상담을 구축합니다:
- 과제: 환자-의료진 간 화상 통화의 안전한 전송
- 해결책: HIPAA 준수 시그널링 API를 사용한 종단 간 암호화 WebRTC
- 결과: SOC 2 Type II 인증, 50만 건 이상의 상담에서 유출 없음
주요 구현:
- MFA를 통한 JWT 인증
- 임시 방 토큰 (상담 후 만료)
- 로그에 PHI 저장 안 함
- 비디오 인프라를 위한 Twilio와의 BAA
환자 포털 API
한 병원 시스템이 환자 접근을 현대화합니다:
- 과제: 일관성 없는 보안을 가진 20개 이상의 레거시 시스템
- 해결책: 중앙 집중식 인증 및 감사를 갖춘 통합 API 게이트웨이
- 결과: 단일 진실의 원천, 간소화된 규정 준수 보고
주요 구현:
- FHIR의 SMART를 사용한 OAuth 2.0
- 중앙 집중식 감사 로깅
- 필드 수준 접근 제어
- 자동 유출 감지
건강 데이터 통합 플랫폼
한 헬스케어 기술 회사가 여러 EHR에서 데이터를 집계합니다:
- 과제: EHR 공급업체마다 다른 보안 모델
- 해결책: 균일한 HIPAA 제어를 갖춘 추상화 계층
- 결과: 100개 이상의 병원 통합, 규정 준수 위반 없음
주요 구현:
- 일관된 암호화를 통한 데이터 정규화
- 테넌트별 감사 추적
- 자동 BAA 추적
- 실시간 규정 준수 대시보드
결론
API를 위한 HIPAA 규정 준수는 인증, 암호화, 접근 제어 및 감사 로깅과 관련된 신중한 아키텍처 결정을 요구합니다. 주요 요점은 다음과 같습니다:
- PHI를 처리하기 전에 모든 공급업체와 BAA 체결
- MFA 및 역할 기반 접근 제어 구현
- 전송 중 (TLS 1.3) 및 저장 시 (AES-256) 데이터 암호화
- 6년 보존 기간으로 모든 PHI 접근 로깅
- 모든 엔드포인트에 최소 필요 표준 적용
- Apidog는 API 문서화 및 규정 준수 워크플로우를 간소화합니다.
FAQ 섹션
API를 HIPAA 준수하게 만드는 요소는 무엇인가요?
API는 ePHI 보호를 위해 HIPAA 보안 규칙에서 요구하는 기술적 보호 장치(암호화, 접근 제어, 감사 로그), 관리적 보호 장치(정책, 교육, BAA), 물리적 보호 장치를 구현할 때 HIPAA 준수합니다.
제 API에 BAA가 필요한가요?
예, 귀하의 API가 적용 대상 기관을 대신하여 PHI를 처리, 가공 또는 저장하는 경우, 귀하는 사업 제휴 기관이며 BAA에 서명해야 합니다. 이는 클라우드 제공업체, API 서비스 및 하위 처리자에게 적용됩니다.
HIPAA에 필요한 암호화는 무엇인가요?
HIPAA는 "전송 중" 및 "저장 시" 암호화를 요구합니다. API 통신에는 TLS 1.3을 사용하고, 저장된 데이터에는 AES-256을 사용하세요. 암호화는 보안 규칙에서 기술적으로 "주소 지정 가능"하지만, 규정 준수를 위해 사실상 필수적입니다.
HIPAA 감사 로그는 얼마나 오랫동안 보존되어야 하나요?
HIPAA는 감사 로그를 생성일 또는 기록이 마지막으로 유효했던 날짜 중 더 늦은 날짜로부터 6년 동안 보존하도록 요구합니다.
HIPAA 준수 인증에 JWT를 사용할 수 있나요?
예, JWT는 올바르게 구현된 경우 허용됩니다: 짧은 만료 시간 (PHI 접근 시 최대 15분), 안전한 저장, 그리고 새로고침 토큰 로테이션. 프로덕션 시스템에서는 항상 MFA와 결합해야 합니다.
최소 필요 표준이란 무엇인가요?
최소 필요 표준은 API가 의도된 목적을 달성하는 데 필요한 최소한의 PHI만을 노출하도록 요구합니다. 필드 수준 필터링 및 목적 기반 접근 제어를 구현하십시오.
감사 로그도 암호화해야 하나요?
예, PHI를 포함하는 감사 로그는 저장 시 암호화되어야 합니다. 또한, 변조를 방지하기 위해 로그를 추가 전용 저장소에 저장하십시오.
유출 통지는 어떻게 처리해야 하나요?
무단 PHI 접근이 발생하면: 1) 유출을 억제하고, 2) 4가지 요소 테스트를 사용하여 위험을 평가하고, 3) 60일 이내에 영향받은 개인에게 통지하고, 4) HHS에 통지하고 (500명 이상인 경우 즉시), 5) 모든 것을 문서화해야 합니다.
HIPAA 워크로드에 클라우드 서비스를 사용할 수 있나요?
예, 제공업체가 BAA에 서명하는 경우 가능합니다. AWS, GCP, Azure 모두 HIPAA 적격 서비스를 제공합니다. 제공업체의 HIPAA 구현 가이드에 따라 서비스를 구성하십시오.
HIPAA 위반에 대한 처벌은 무엇인가요?
민사 벌금은 위반 건당 100달러에서 50,000달러까지 부과되며, 위반 유형별 연간 최대 150만 달러입니다. 형사 벌금은 최대 250,000달러의 벌금과 최대 10년의 징역을 포함합니다.
