블로그 목록
techIoT 플랫폼OTA펌웨어A/B 파티션코드 서명

실패해도 기기가 살아있는 업데이트: 원격 펌웨어 배포 설계기

이미 고객 손에 있는 기기의 소프트웨어를 원격으로 바꾸는 일은 IoT에서 가장 위험한 작업이라, 잘못 만들면 한 번의 버튼 클릭이 전량 회수로 이어집니다. 벽돌이 되지 않게, 가짜 펌웨어가 들어오지 않게, 취약한 옛 버전으로 되돌아가지 않게 만든 구조를 정리했습니다.

OpenIoT

OpenIoT 플랫폼팀

조회 11
실패해도 기기가 살아있는 업데이트: 원격 펌웨어 배포 설계기

원격 업데이트를 설계하는 내내 저희가 붙들고 있던 질문은 어떻게 성공률을 올릴까가 아니라 실패했을 때 아무 일도 일어나지 않게 하려면 무엇이 필요한가였습니다. 이미 고객 손에, 그것도 천장과 지하 기계실에 달려 있는 기기를 다루는 이야기라 더 그랬습니다.


새벽 3시에 정전이 나면 기기가 벽돌이 됩니다

펌웨어는 기기 안에 들어 있는 소프트웨어라 스마트폰의 OS 업데이트와 같은 것이라고 보면 되는데, 다른 점이 하나 있습니다. 스마트폰은 문제가 생기면 사용자가 직접 만질 수 있지만 천장에 붙은 센서나 지하 기계실의 제어기는 그럴 수 없습니다.

새벽 3시, 서버가 1,000대의 센서에 새 펌웨어를 내려보내고 850대가 다운로드를 마치고 자기 내부 저장소에 새 소프트웨어를 덮어쓰기 시작합니다. 그 순간 해당 지역에 정전이 발생합니다.

전기가 돌아왔을 때 그 기기들 안에는 절반만 쓰인 소프트웨어가 들어 있습니다. 옛 버전은 이미 지워졌고 새 버전은 완성되지 않았으니 기기는 켜지지 않습니다.

업계에서는 이 상태를 "벽돌이 됐다"고 부르는데, 전원은 들어오는데 아무것도 못 하는 물건이 됐다는 뜻입니다.

"옛 버전을 먼저 지웠다"는 한 줄이 이 그림의 전부입니다. 정전 자체가 아니라 되돌아갈 자리를 없앤 채 작업을 시작한 것이 기기를 벽돌로 만듭니다.

위험은 네 갈래입니다. 중단에 취약하면 업데이트 중 정전이나 통신 끊김으로 기기가 부팅 불가가 되어 현장 방문 외에 복구 수단이 없고, 잘못된 펌웨어를 전면 배포하면 버그 있는 버전을 1만 대에 한 번에 뿌려 회수·출장 비용이 제품 가격을 넘습니다. 가짜 펌웨어 주입을 막지 못하면 공격자가 전 기기를 장악해 기기가 그대로 감시 카메라나 공격 발판이 되고, 취약 버전으로의 강등은 보안 구멍을 막은 뒤에도 옛 버전으로 되돌리는 기능 자체가 공격 수단이 되게 만듭니다.

두 번째의 비용 구조가 특히 비대칭적입니다. 서버 소프트웨어는 잘못 배포해도 되돌리면 그만이지만 기기는 1만 대가 부팅을 못 하면 1만 곳을 사람이 찾아가야 하고, 제품 단가가 5만 원이어도 출장 한 번에 그 이상이 듭니다.

롤백은 안전장치이면서 동시에 공격면입니다

네 번째는 직관에 반해서 자주 놓칩니다. "문제가 생기면 이전 버전으로 되돌린다"는 건 소프트웨어 개발의 상식적인 안전장치인데, 그 이전 버전에 보안 취약점이 있었다면 이야기가 달라져서 공격자에게 "기기를 뚫린 상태로 되돌리는 정식 기능" 을 제공한 셈이 됩니다. 국내 IoT 보안인증 기준도 이 지점을 명시적으로 금지해서 알려진 취약점이 있는 구 버전으로 되돌리는 기능은 제공하지 않아야 한다는 조항이 들어 있고, 이 모순을 어떻게 푸느냐가 이 글의 중심 주제 중 하나입니다.


새 소프트웨어를 어느 자리에 쓸 것인가가 안전성을 정합니다

핵심 질문은 의외로 단순합니다. 기기의 저장 공간은 몇 MB 수준으로 스마트폰의 1/1000 규모인데, 그 좁은 공간을 어떻게 나누느냐가 안전성을 결정합니다.

방식어떻게 동작하나장점결정적 한계
① 전체 이미지 덮어쓰기지금 실행 중인 자리를 새 버전으로 그대로 덮음저장 공간을 가장 적게 씀. 구현이 가장 단순덮어쓰는 도중에 중단되면 복구 불가. 옛 버전이 이미 사라졌기 때문
② A/B 이중 파티션저장 공간을 A·B 두 칸으로 나눔. 지금 A로 돌고 있으면 새 버전은 B에 씀. 다 쓴 뒤 B로 재부팅중단돼도 A는 그대로. 새 버전이 부팅에 실패해도 A로 자동 복귀앱 이미지를 넣을 공간이 두 배 필요
③ 차분(델타) 업데이트옛 버전과 새 버전의 달라진 부분만 전송해 기기가 조립전송량이 크게 줄어듦. 저대역 환경에서 통신비·시간 절약조립 과정 자체가 실패 지점. 혼자서는 안전성을 못 줌

가운데 칸의 "도는 곳"과 "쓰는 곳"이 서로 다른 칸이라는 점을 봐주세요. 왼쪽은 그 둘이 같은 자리라서 중단이 곧 사고가 되고, 오른쪽은 안전과는 다른 축의 이야기입니다. ②와 ③은 경쟁 관계가 아니라 ②는 안전하게 바꾸는 방법이고 ③은 적게 보내는 방법이어서, 성숙한 시스템은 ② 위에 ③을 얹습니다.

②를 비유하면 문을 하나 더 다는 것입니다. 현관 자물쇠를 새것으로 바꿀 때 옛 자물쇠를 뜯어내고 시작하면 작업 중 문제가 생겼을 때 집에 못 들어가지만, 옆에 문을 하나 더 달아 두고 새 자물쇠를 거기 달면 새 문이 안 열려도 옛 문으로 들어가면 됩니다.

배포 전문 제품들은 A/B를 논쟁 대상으로 두지 않았습니다

오픈소스·상용 IoT 플랫폼을 대조하면서 배포 쪽 전문 제품들(Mender · Golioth · balena · Memfault 등)의 구조를 함께 봤습니다. A/B 이중 파티션은 논쟁의 대상이 아니라 기본 사양이었고 여기서 저장 공간을 아끼는 팀은 없었습니다. 차분 업데이트는 전문 배포 제품들이 갖추고 있었지만 안전성이 아니라 비용 최적화 영역이었습니다. 단계적 배포에는 배포 대상군을 영속적으로 정의하는 개념이 있었고, 한 대상군에 활성 배포는 하나만 허용하면서 실패율 초과 시 자동 중단을 짝으로 붙이고 있었습니다.

정리하면 A/B 이중 파티션을 바닥에 깔고 그 위에 배포 통제 장치를 얹는 것이 업계의 표준 형태였습니다.


그래서 안전장치를 다섯 겹으로 쌓았습니다

A/B 이중 파티션을 기본 구조로 확정하고 그 위에 네 겹을 더 얹었는데, 하나하나가 앞에서 본 위험 하나씩에 대응합니다.

실패해도 기기는 살아 있습니다

기기의 저장 공간을 부트로더, 슬롯 선택 영역, 앱 이미지 A와 B, 설정·인증서 영역, 서명 검증용 공개키, 감사기록으로 나눴습니다. 설정·인증서 영역은 암호화가 필수이고 공개키는 읽기 전용이며 감사기록에는 삭제 기능이 없습니다.

업데이트는 A로 운영하면서 B에 새 버전을 기록하고 다 쓴 뒤 B로 재부팅하는 순서로 진행되는데, 핵심은 "쓰는 곳"과 "도는 곳"이 절대 겹치지 않는다는 것입니다. B에 기록하는 도중 정전이 나도 A는 손대지 않았으므로 전기가 돌아오면 기기는 옛 버전으로 정상 부팅하고, 업데이트는 실패하고 다시 시도하면 됩니다.

여기에 재부팅 직후의 자동 검증을 더했습니다. 새 버전으로 부팅했다고 끝이 아니라 기기가 스스로 서명 검증과 자체 점검과 무결성 확인을 거치고, 어느 단계에서든 실패하면 이전 슬롯으로 되돌아갑니다. 되돌아간 뒤에도 서비스 중단이나 사용자 데이터 손실 없이 정상 운영이 이어져야 한다는 것을 요구사항으로 못 박았습니다.

어느 화살표를 타든 결국 정상 운영 칸으로 돌아온다는 점을 봐주세요. 새 버전으로 확정되거나 옛 버전으로 복귀하거나 둘 중 하나이고 중간에서 멈추는 상태가 없어서, 업데이트 실패가 A/S 사건이 아니라 재시도 대상이 됩니다. 실패율이 0이 되는 게 아니라 실패의 결과가 "출장"에서 "다음 기회에 다시"로 바뀌는 것입니다.

우리가 서명한 것만 설치됩니다

A/B 파티션은 중단 위험을 막지만 가짜 펌웨어에는 무력해서, 공격자가 자기 펌웨어를 B에 밀어넣으면 그건 정상적으로 부팅됩니다. 그래서 펌웨어에 디지털 서명을 붙이고 기기가 설치 전에 검증하는데, 일상의 비유로는 인감과 인감증명입니다. 회사가 개인 도장으로 펌웨어에 도장을 찍고 기기는 공장에서 넣어 둔 인감증명으로 그 도장이 진짜인지 대조하며, 도장이 안 맞으면 설치를 시작조차 하지 않습니다.

운영 규칙 두 가지를 함께 정했습니다. 서명키는 사람이 만지지 않고 클라우드 키 관리 서비스 안에서만 서명하는데, 개발자 노트북에 서명키가 있으면 노트북 한 대가 전 기기의 열쇠가 되기 때문입니다. 그리고 미서명 펌웨어는 배포 API가 거부해서 사람의 주의력이 아니라 시스템이 차단합니다.

가짜 펌웨어도 정상 펌웨어와 똑같은 문 앞에 선다는 것이 요점입니다. 통과 여부를 가르는 건 어디서 왔느냐가 아니라 도장이 맞느냐이고, 그 도장을 찍는 열쇠는 사람 손에 없습니다.

전송 구간도 함께 잠갔습니다. 펌웨어는 암호화된 통신 채널로만, 단기간만 유효한 일회성 주소로 내려받습니다. 기기는 다운로드 전에 업데이트 서버 인증서의 유효기간과 폐기 여부까지 확인합니다. 여기에 매니페스트 공개를 얹어 각 버전의 해시값·서명·대상 모델·릴리스 노트를 공개 주소로 노출하는데, 고객사가 받은 파일이 우리가 배포한 그 파일인지 독립적으로 검증할 수 있게 하기 위해서입니다.

기기도 독립적으로 다운그레이드를 거부합니다

가장 흔한 설계는 "서버가 허용한 버전만 설치한다"인데 합리적으로 보이지만 서버가 뚫리면 전부 무너집니다. 공격자가 서버를 장악한 뒤 "2년 전 취약 버전으로 되돌려라"라고 명령하면 기기는 순순히 따르기 때문에, 판단을 두 곳에 나눠 뒀습니다.

판정 화살표 세 개가 전부 기기 쪽에서 자기 자신을 향한다는 점을 봐주세요. 서버는 이 버전으로 갱신하라고 알려줄 뿐 설치 여부를 최종적으로 정하는 건 기기이고, 최소 안전 버전은 이보다 낮으면 알려진 보안 구멍이 있다는 선입니다. "서버가 나쁜 지시를 내리지 않도록 관리합니다"와 "나쁜 지시를 받아도 기기가 거부합니다"는 신뢰 수준이 다른데 저희는 후자입니다.

같은 논리를 서버 쪽 카탈로그에도 걸어서, 취약점이 확인된 버전은 폐기로 표시되고 그 순간부터 배포 대상에서도 롤백 대상에서도 자동으로 빠집니다. 미조치 취약점이 남아 있는 버전과 서명이 안 된 버전도 같은 게이트에서 걸립니다.

1만 대에 한 번에 뿌리지 않습니다

아무리 테스트해도 현장에는 실험실에 없는 조건이 있습니다. 특정 통신사, 특정 공유기, 특정 하드웨어 리비전 같은 것들이라 배포를 만들 때 대상과 비율을 함께 지정합니다. 대상은 장소 단위나 기기 직접 선택으로 정하되 해당 모델의 기기만 후보에 오르고, 1차로 몇 퍼센트에 보낼지 고른 뒤 성공·실패·진행 중 대수를 실시간 집계해 확대할지 중단할지 판단합니다.

왼쪽 아래 점선을 봐주세요. 배포가 잘못돼도 피해가 1차 웨이브 안에서 멈추고 그 안에서 실패한 기기조차 옛 버전으로 살아 있어서 두 겹의 안전장치가 겹쳐 있는 지점이고, 배포를 취소해도 이미 설치를 마친 기기는 그대로 유지되며 진행 중이던 것만 멈춥니다. 1만 대 중 10%면 1,000대이고 그중 실패한 기기는 A/B 파티션 덕분에 살아 있습니다.

기기가 마음대로 재부팅하지 않습니다

마지막 겹은 성격이 다릅니다. 기술적 안전이 아니라 사용자 통제권입니다. 펌웨어 설치에는 재부팅이 따르는데 재부팅은 하필 그 순간에 그 기기가 필요한 사람에게는 장애와 구분되지 않습니다. 매장 결제 단말이나 공장 라인 센서나 난방 제어기는 전부 "지금은 곤란한 시간"이 있어서, 배포 지시를 받아도 기기가 곧바로 설치하지 않습니다.

사용자는 새 버전을 앱으로 통지받고 지금 설치할지 며칠 미룰지 고를 수 있으며, 자동 업데이트를 끄거나 "매일 새벽 2~4시" 같은 업데이트 창을 지정할 수 있고, 진행 중인 설치에 개입하거나 이력을 조회할 수도 있습니다. 그리고 업데이트 수행과 결과는 무조건 감사기록에 남습니다. 어느 버전에서 어느 버전으로, 실패했다면 사유까지 남는데 이 기록은 삭제 기능을 아예 만들지 않아서 관리자 화면에도 API에도 SDK에도 없고 보존기간이 지나면 자동 만료로만 사라집니다.

①~⑥ 중 어디서 멈춰도 기기는 옛 버전으로 정상 동작한다는 점이 다섯 겹의 결론입니다. 그리고 마지막 두 화살표인 결과 보고와 집계가 있어야 운영자가 확대할지 중단할지 판단할 수 있습니다.


롤백 기능이 보안 기준과 정면으로 충돌했습니다

초기 설계에는 "임의 버전으로 되돌리기"가 최우선 기능으로 들어가 있었습니다. 운영 관점에서는 당연한데 새 버전에 문제가 생기면 되돌릴 수 있어야 하기 때문입니다. 그런데 보안 기준을 대조하는 과정에서 이게 금지 항목과 정면으로 충돌한다는 것을 발견했고, 돌아보면 여기서 한참 헤맸습니다. 처음에는 운영 안전성이냐 보안 인증이냐의 택일 문제로 보였는데, 최소 안전 버전이라는 개념 하나로 풀렸습니다.

오른쪽에도 되돌리기 화살표가 살아 있다는 점을 봐주세요. 기능을 지운 게 아니라 도착지 목록에서 위험한 칸만 뺐는데, 조항이 금지한 건 "롤백"이 아니라 "취약 버전으로의 롤백"이었기 때문입니다. 롤백 후보를 최소 안전 버전 이상으로만 제한하고 취약점이 확인된 버전은 카탈로그에서 폐기 표시해 후보에서 자동 제외하니, 운영 안전장치는 그대로 남고 공격면만 잘려 나갔습니다. 여기서 배운 것은 "A냐 B냐"로 막힐 때는 대개 문제 정의가 한 단계 거칠다는 것입니다.

자동 중단을 넣으려다 선행 조건이 없다는 것을 발견했습니다

외부 플랫폼과 대조하면서 단계적 배포에는 거의 항상 실패율 자동 중단이 짝으로 붙어 있다는 것을 확인하고 넣으려고 보니, 무엇을 실패로 셀 것인가가 정해지지 않았습니다. 설치 실패는 셀 수 있어서 서명 검증 실패나 다운로드 실패나 부팅 실패는 기기가 결과를 보고하는데, 진짜 위험한 실패는 설치는 성공했는데 그 뒤에 기기가 자꾸 재시작되는 경우였습니다.

이걸 감지하려면 기기의 비정상 종료 기록을 수집하고 버전별로 묶어 볼 수 있어야 "새 버전 배포 후 크래시가 3배" 같은 판단이 서는데, 지금 설계에는 이벤트 로그 수집은 있지만 크래시 원인 분석 수준의 관측 기능은 없습니다. 그래서 순서를 명시적으로 뒤집어 기기 관측성을 자동 중단의 선행 과제로 로드맵에 못 박고 그때까지는 사람이 보고 취소하는 수동 중단을 제공하기로 했습니다. 실패한 기기와 사유를 목록으로 보여주는 화면이 그래서 먼저 만들어졌습니다.

근거 없는 자동화는 자동화가 아니라 랜덤 중단입니다. 순서를 지키는 쪽을 택했습니다.

차분 업데이트를 지금은 넣지 않기로 했습니다

전문 배포 제품들은 차분 업데이트를 갖고 있고 저희는 없는데, 이건 명시적으로 인지하고 내린 판단입니다. 얻는 것은 전송량 감소로 저대역 환경에서 통신비와 시간을 아끼는 것이지만, 잃는 것은 조립 실패라는 새로운 실패 지점과 기기의 현재 버전 조합만큼 차분 파일을 만들어 관리해야 하는 부담입니다. 그리고 안전성 기여는 없는데 차분은 비용 최적화지 안전장치가 아니기 때문입니다.

초기 제품군이 Wi-Fi 환경이 주력이고 전체 이미지가 몇 MB 수준이라 감당 가능해서, 안전장치를 먼저 완성하고 최적화는 뒤로 미뤘습니다. 다만 이걸 "없는 기능"이 아니라 "셀룰러 제품군이 들어오는 시점의 과제" 로 문서에 남겼고, 이 부분은 지금도 더 나은 방법이 있을 것 같습니다.

기기 보안의 상당 부분이 칩 내부의 일회성 설정에 의존한다는 것도 미리 처리해야 했습니다. 보안 부팅 활성화나 저장소 암호화나 디버그 포트 차단은 한 번 굽으면 되돌릴 수 없습니다. 안 구워진 채 출하되면 펌웨어 업데이트로도 고칠 수 없습니다. 그래서 개발용 보드와 출하용 보드의 설정 프로파일을 분리하고 양산 지그가 자동으로 굽도록 공정을 설계했는데, 수동 작업으로 두면 반드시 누락 물량이 나오기 때문입니다.


지금 손에 있는 것을 그대로 적습니다

현재 이 구조는 설계 확정 + 동작하는 화면 프로토타입 단계이고 성능 측정치나 운영 지표는 아직 존재하지 않습니다. 지금까지 이야기한 것을 한 장으로 모으면 이렇습니다.

게이트가 두 벌이라는 점이 이 글 전체의 요약입니다. 왼쪽 플랫폼에서 한 번 거르고 받은 기기가 같은 판단을 한 번 더 하며, 어느 쪽으로 끝나든 마지막은 지울 수 없는 기록으로 모입니다.

저장소 레이아웃이 고정됐는데 A/B 두 슬롯, 슬롯 선택 영역, 암호화된 설정·인증서 영역, 삭제 API가 없는 감사기록 영역이고 하드웨어 설계와 물려 있어서 나중에 못 바꿉니다. 서버 쪽 배포 절차와 기기 쪽 설치 절차도 함께 고정했습니다.

서버: 빌드 → 취약점 스캔 → 코드 서명 → 매니페스트 공개 → 최소 안전 버전 갱신 → 단계적 배포
기기: 버전 확인 → 사용자 인가 확인 → 서버 인증서 검증 후 다운로드 → 코드 서명 검증
      → 비활성 슬롯에 기록 → 재부팅 후 검증 → (성공) 결과 보고 / (실패) 이전 슬롯 복귀 + 사유 보고

프로토타입은 클릭되는 화면으로 만들어 이 구조가 화면으로 성립하는지 확인했습니다.

화면확인한 것
펌웨어 목록버전·모델·해시·크기와 함께 상태 태그: "최소 안전 버전" · "폐기" · "미서명" · "취약점 N건" · "배포 가능". 하단에 배포 작업 목록
펌웨어 상세개요 / 매니페스트 / 배포 이력 3개 탭. 보안 게이트 패널이 취약점 스캔·코드 서명·폐기 여부를 통과/차단으로 표시하고, 차단이면 배포 버튼이 비활성화됨
배포 마법사대상 선택 → 비율 선택 → 확인 3단계. 해당 모델 기기만 후보에 오르고, 비율을 고르면 1차 웨이브 대수가 즉시 계산됨
배포 작업 상세전체·성공·실패·진행 중 집계. 실행 로그 표에 기기별로 "어느 버전 → 어느 버전 · 시각 · 결과 · 실패 사유"가 남고, 진행 중이면 취소 가능
배포 플로우 컴포넌트확인 단계에서 대상 수·비율·필요 권한·해시를 한 번에 보여주고 실패 시 동작을 사전에 명시

가장 유용했던 건 보안 게이트가 화면에 그대로 보인다는 점이었습니다. 취약점이 남아 있는 버전을 클릭하면 "미조치 취약점 1건: 배포 차단"이 뜨고 버튼이 눌리지 않으며, 폐기된 버전은 롤백 버튼에서도 "롤백할 수 없습니다"와 사유를 보여줍니다. 덕분에 비개발자도 게이트 규칙을 눈으로 검토할 수 있었는데, "이 버전은 왜 배포가 안 되나요"라는 질문에 화면이 스스로 답합니다.

검증 산출물로는 외부 플랫폼 대조에서 나온 누락 4건, 보안 인증기준 7개 항목의 펌웨어 요구사항 전개, 화면-기능 전수 대조, 그리고 릴리스 산출물 목록이 남았습니다. 마지막 줄이 B2B에서 의외로 큰데, 고객사가 IoT 보안인증을 받을 때 필요한 서류 중 상당수가 우리 배포 파이프라인이 자동으로 만들어 두는 것이기 때문입니다.


"서버를 믿는다"는 가정을 지운 것이 가장 큰 결정이었습니다

설계 내내 반복해서 물었던 질문은 우리 서버가 뚫렸다고 가정하면 이 기능은 무엇을 할 수 있게 되나였습니다. 배포 시스템에서 이 질문은 아프게 돌아오는데, 배포 서버는 정의상 모든 기기에 코드를 심을 수 있는 권한을 가진 시스템이기 때문입니다. 그래서 판단을 기기 쪽에도 복제해 서명 검증도 최소 안전 버전 판정도 기기가 독립적으로 하게 했습니다. 서버가 시키는 대로만 하는 기기는 서버가 무너지는 날 함께 무너집니다.

금지 조항은 대개 기능이 아니라 조건을 금지한다는 것도 배웠습니다. "취약 버전으로의 롤백 금지"를 처음 봤을 때는 롤백 기능 자체를 포기해야 하는 줄 알았는데, 다시 읽으니 금지된 건 취약 버전이라는 조건이었습니다. 그 뒤로 기준과 부딪힐 때 "이 기능을 없애야 하나"가 아니라 "어떤 조건이 금지된 건가"를 먼저 확인하는 습관이 생겼는데, 대부분은 조건을 좁히면 기능이 살아남습니다.

안전장치와 최적화를 섞으면 둘 다 늦어진다는 것도 확인했습니다. 차분 업데이트는 매력적이고 효과를 숫자로 말하기도 쉽지만 그건 비용 최적화이고 A/B 파티션과 코드 서명은 안전장치인데, 둘을 같은 목록에 놓고 우선순위를 매기면 성격이 다른 것을 비교하게 되어 판단이 흐려집니다.

고객이 얻는 것근거
업데이트 실패가 출장으로 이어지지 않음A/B 이중 파티션 + 부팅 실패 시 자동 복귀
가짜 펌웨어가 설치될 수 없음코드 서명 검증 + 서명키를 사람이 만지지 않는 구조
서버가 뚫려도 취약 버전으로 강등되지 않음기기가 최소 안전 버전을 독립 판정
잘못된 배포의 피해 범위가 제한됨단계적 배포 + 즉시 취소 + 게이트 통과 버전만 배포
업데이트가 사용자 일정을 침범하지 않음승인·연기·업데이트 창·자동 업데이트 on/off
인증·감사 대응 서류가 자동으로 쌓임삭제 불가능한 업데이트 이력 + 릴리스마다 보관되는 검증 산출물

첫 줄이 이 설계에서 가장 신경 쓴 부분입니다. 업데이트를 성공시키는 구조는 만들기 쉽지만, 실패해도 아무 일도 일어나지 않는 구조가 어렵습니다.

읽어주셔서 감사합니다.


IoT 서비스,
지금 바로 시작하세요

디바이스 연결부터 대시보드까지 올인원

무료 플랜으로 부담 없이 체험