Owner review 5, lane J: 본인인증 at sign-up (providers, integration) and juniors (2026-10-12)
Status: Draft · Date: 2026-10-12 · Lane J of owner review 5. Inputs: lane F of review 4 (§3.3 linking by CI, §4 the ladder and the law), the sign-in board flat-v2-auth.jsx (frames vi-*, lines 885-970), the shipped onboarding under-14 gate (packages/features/onboarding/src/onboarding-wizard-screen.tsx:134,352, onboarding-step-under-14-gate.tsx), docs/canon/korean-market.md, and sources fetched on 2026-10-12. Audience: Korean club members aged 40 to 60, plus a few juniors. Nothing outside this file was changed.
Owner, review 5. "Do some research on how to take care of this. Should we adopt third-party authenticators like 패스 or 토스 or naver 인증?" and "Juniors can stop for now? What do you think is the best way to go? We can expand later."
0. Evidence tags and limits
| Tag | Meaning |
|---|---|
| P | First-party page fetched today (provider, regulator, PortOne docs) |
| S | Secondary: news, blog, vendor blog, forum |
| B | Background knowledge I did not re-verify today; treat as a lead, not a citation |
| C | Needs counsel or the vendor's written answer before it is relied on |
Limits, stated plainly. Prices per check are not published by NICE, KCB, SCI, Danal, KG이니시스 or PortOne on any page I could reach; every search returned none. I therefore give no quoted price. The cost model in §4.3 is a formula with illustrative unit prices, marked as assumptions. First-party evidence of what 당근, 번개장터, 숨고, 무신사, 배민, 야놀자 and the sports apps do at sign-up was not found; §3 says so per app instead of guessing. The PIPC (개인정보보호위원회) page for the guardian-consent methods redirected and I could not read the 시행령 §17-2 text itself.
1. The options, compared
1.1 What the aggregator in front of us can do (PortOne v2)
Our canon says PortOne v2 runs in a WebView only (docs/canon/korean-market.md). PortOne's v2 identity-verification guide (P: 본인인증 연동하기) lists three supported channels:
- 다날 휴대폰 본인인증.
- KCP 휴대폰 본인인증.
- KG이니시스 통합인증, whose listed methods are PASS, Naver, Toss, Kakao, 금융인증서, Shinhan, KB Mobile and Samsung Pass.
The flow is one call: PortOne.requestIdentityVerification({ storeId, identityVerificationId, channelKey }); on success the browser sends identityVerificationId to our server, and the server looks it up through the REST API and reads the customer data only when status is VERIFIED (P, same page; the request parameters are on the SDK reference). Mobile redirect flows set redirectUrl and get the result back as query parameters. Danal and KCP also offer an API-only mode (name, phone, first 7 digits of the resident number, carrier, SMS or APP), which means collecting a resident-number prefix ourselves; we should not use it (see §2.1).
What comes back, by channel (P, same page; "contract" means a written extra agreement with the vendor):
| Field | 다날 | KCP | KG이니시스 통합인증 |
|---|---|---|---|
ci | needs enrollment at contract | depends on merchant settings | always, except Kakao (separate documents) |
di | always | always | not provided |
gender | always | always | always, except Kakao-only cases |
phoneNumber | needs extra contract | always | always |
isForeigner | needs extra contract | always | always, except Kakao and Naver (the user types it, so it is unverified) |
operator | needs extra contract | always | not provided |
The page says nothing about name and birthDate per channel; the type lists them (name, birthDate as YYYY-MM-DD). The REST reference page I fetched showed only id, name, operator (truncated), so the full object type should be read in the SDK before the build (C: vendor). The page gives no price.
1.2 Option table
| Option | User steps | Returns | Cost per check | Integration | Contract | Coverage |
|---|---|---|---|---|---|---|
| 휴대폰 본인확인 (NICE, KCB, SCI, via Danal or KCP) | Pick carrier, enter name, birth, phone; SMS code, or the PASS app path (APP mode, no SMS) | name, birth, gender, phone, CI, DI, foreigner flag, subject to the contract fields above | Not published (S: only the carriers' consent forms name NICE and SCI as the CI/DI generators for SKT, SK telecom form). Quote needed | PortOne v2 channel (WebView or SDK) or the agency's own page | A merchant contract with the 본인확인기관 or PG, a business registration, and a security-check application for CI/DI (NICE publishes a CI/DI request form with a checklist, S: NICE CI/DI form) | Needs a phone in the person's own name: family-name lines are refused (S: yellowit). MVNO (알뜰폰): the carrier forms name the three carriers; MVNO coverage is not confirmed (C: vendor). Foreigners: flag only, registration-card holders |
| PASS app path (SKT, KT, LG U+) | Open PASS, authenticate (face, PIN, biometrics), no code typing | Same data as 휴대폰 본인확인; PASS is a carrier channel inside the same service | Same as above | Selected as APP mode in the phone channel, or as a method inside KG이니시스 통합인증 | Same contract | Needs a carrier line and the PASS app; helps the 40-60 audience (no code typing); same name-on-line limit |
| 민간 인증서 (Toss, Naver, Kakao, PASS 인증서, Samsung Pass, KB) | Open the chosen app, approve; 1 to 2 taps if already enrolled | Depends on the channel: through KG이니시스 통합인증 CI, gender, phone, foreigner flag come back, no DI; Kakao CI needs separate documents; Naver and Toss foreigner flag is unverified for Naver | Not published | One KG이니시스 통합인증 channel on PortOne, or each provider directly | The aggregator contract; a direct Toss or Naver contract is separate (see below) | Needs an enrolled certificate in that app; people without one fall back to phone verification, so the picker must offer both |
| 공동인증서 / 금융인증서 | Install or fetch a certificate, password | 금융인증서 is listed as a 통합인증 method (P); 공동인증서 is not in the PortOne list | n/a | Inside 통합인증 (금융인증서 only) | Same as aggregator | Poor on phones; skip |
| Toss's own 본인확인 for partners | Toss app approval, without waiting for an SMS | The page promises "CI, DI" for sign-up and account lookup (P: toss.im/tosscert); it does not list name, birth or phone fields | Not stated | Developer guide linked from the page; web or app not specified | Toss states it provides 전자서명, 마이데이터 통합인증 and 본인확인 services (P: Toss 약관); the partner application is via its 인증 사업 문의 page | 2,000+ partner institutions (P, same page); only for people with a Toss account |
| Kakao 인증 for partners | Kakao app approval | Kakao's account_ci from Kakao Login is not a 본인확인기관 result; Kakao says it "is not an identity verification agency" (P, lane F §1.1) | Not stated | Kakao Login scope (biz app) or the 통합인증 channel | Biz app and a 3-5 business day review for the login scope (P, lane F) | Not a substitute for 본인인증 by itself |
| 다날 / KCP direct | As the phone path | See table above | Not published | PortOne channel or direct | PG merchant contract | Same as the phone path |
Answer to the owner's question. Do not adopt Toss, Naver or PASS one by one. They are methods of one 본인확인 service, and the aggregator's 통합인증 already puts PASS, Naver, Toss, Kakao and the bank certificates behind one screen (P). Contracting each provider separately multiplies contracts for a small gain.
2. Which one returns a CI usable as our person key?
2.1 Legal limits
- 정보통신망법 §23-2: services may not collect resident registration numbers except where a law allows or the service is a designated 본인확인기관; §23-3: the 본인확인기관 designation. The current table of contents also lists 연계정보 generation and safeguards in later sections (lane F §3.3 and §4.2, L: elaw table of contents). We never receive or type a 주민등록번호; this rules out the Danal and KCP API-only mode (it takes the first 7 digits of the resident number) (P).
- Storing the CI. Lane F recommended storing the vendor's CI hashed or encrypted with a unique constraint. KISA treats CI as personal information if it can be combined with other data (lane F, S). Counsel must confirm (C): the legal basis to store CI for the duplicate-account purpose; the retention period; whether a one-way hash (keyed with a server secret) is acceptable in place of the raw CI; the consent wording; and whether our service must be separately approved to receive CI (NICE's CI/DI application form and checklist suggest a per-service approval, S).
- DI. DI is per-service; KG이니시스 does not provide it (P). With CI alone we lose nothing for one account per person, but CI is the more sensitive value (it links across services), so the hash and key custody matter more (C).
2.2 Does a 민간 인증서 path give the same CI as the phone path?
Intended answer: yes, for the same person. The CI is derived by a 본인확인기관 from the resident number, so any path that ends in a 본인확인기관's CI should yield the same value for the same person (B, as lane F §3.3 states; not verified with a vendor today). Two exceptions already visible in the evidence:
- Kakao's own CI comes from Kakao, not a 본인확인기관, and needs separate documents even inside KG이니시스 (P). Do not mix it with the vendor CI in one unique key.
- Toss and Naver CI come back through 통합인증 (P: CI "always, except Kakao"), so they are the vendor's CI. Whether the Toss-direct CI equals the 이니시스 CI is not stated (C: vendor).
Required check before launch (C): enrol one real person through the phone path and through two 통합인증 methods; the three CI values must be identical. This is a one-hour test with the chosen vendor, and it decides whether "one account per person" holds across methods.
3. What Korean apps use at sign-up
| App | At sign-up (what I could establish) | Evidence |
|---|---|---|
| 토스 | 본인인증 is the account; Toss also sells the same identity service to 2,000+ institutions (P: toss.im/tosscert) | P |
| 당근 | Phone number (SMS) and a neighbourhood check; a blog says one number per account (lane F §4.3; S: jab-guyver); no 본인인증 found | S |
| 크몽 | Account only; experts give real name, phone, birth date and CI before listing (lane F §4.3, P) | P |
| 카카오뱅크, 번개장터, 숨고, 무신사, 배민, 야놀자 | Not found. Searches returned no first-party page for the sign-up step. A bank is by law identity-verified (B); the others I will not guess | none |
| Korean sports and club apps (아이엠그라운드, 플랩풋볼, tennis club apps) | Not found. Searches returned the general under-14 rules but no page of these apps (S: thecheck) | none |
What the evidence supports. Lane F's pattern holds: open marketplaces use a phone or a social login and ask for identity where money leaves the person. Our owner has now chosen to verify at sign-up. That is stricter than the community norm but matches Toss and the Korean habit of "one person, one account" (S: 카카오페이 refuses a phone not in the person's name, lane F). The cost is the drop-off at the verification screen, which §4 handles by keeping the screen short and offering PASS first.
4. Recommendation
4.1 One integration, with a fallback
Primary: PortOne v2 identity verification on the KG이니시스 통합인증 channel. One screen offers PASS, Toss, Naver, Kakao and the bank certificates; it returns CI, gender, phone, foreigner flag, name and birth date through the REST lookup, with no DI (P). It reuses the PortOne account and WebView rule we already have for payments (docs/canon/korean-market.md), so there is no second SDK and no resident-number handling.
Fallback: PortOne v2 휴대폰 본인인증 on 다날 (or KCP) in WebView mode. For people with no enrolled app, and as the second channel if the 이니시스 contract is slow. Ask for CI and DI in the Danal contract at enrollment, because the CI field "needs enrollment at contract" (P).
Trade-off. One aggregator means one point of failure and one price list; a second channel keeps sign-up alive (decided by evidence: the three channels exist and return CI; the choice of 이니시스 as primary is by coverage, not by price, which is unknown). If the quote makes 이니시스 expensive, the order can reverse without changing the app: only channelKey changes.
4.2 The user's flow and the screens the board should draw
Flow (review 4 order): provider login, 본인인증, 약관, 첫 시작.
- vi-intro (exists): why we verify; one button, 본인인증하기. Add a one-line promise: "주민등록번호는 받지 않아요" (we never receive the resident number).
- Method picker is the aggregator's own screen (
vi-agency, exists): PASS first, then Toss, Naver, Kakao; a "휴대폰 번호로 인증" row for people with no app. Do not draw our own picker; the vendor's screen is the single source. - vi-result (exists): masked name and birth date; continue.
- Existing failure frames hold: busy, cancel, fail, dup, exit.
New frames to draw:
- vi-nophone: "본인 명의 휴대폰이 없어요" help state (a family-name line is refused), with the one way out: use a certificate app, or ask a member of the club to host (copy to be agreed). Hint, not a new flow.
- vi-foreign: a foreigner path. The flag is verified for PASS and phone, user-typed for Naver and Kakao (P), so the foreigner flag should be taken only from the phone or PASS result (C).
- vi-u14 and a new vi-14-18 (see §5.4).
4.3 Cost model at 1k, 10k and 100k sign-ups
The unit price is unknown (no published list). Formula: cost = sign-ups x attempts per success x unit price. Assume 1.2 attempts per success (cancels and failures; B). Illustrative unit prices only, to show the order of magnitude; the real quote replaces them.
| Sign-ups | At 50 KRW | At 100 KRW | At 200 KRW |
|---|---|---|---|
| 1,000 | 60,000 | 120,000 | 240,000 |
| 10,000 | 600,000 | 1,200,000 | 2,400,000 |
| 100,000 | 6,000,000 | 12,000,000 | 24,000,000 |
Read this as: even at the high end the check is small beside the value of one trusted account, but at 100k it is a real line item, and volume tiers are usually negotiated (B). Ask for tiered pricing and for what counts as a billable attempt (success only, or every request) in the first email (C: vendor).
4.4 Contracts and timing
| Item | Needs | Time (my estimate, B; ask the vendor) |
|---|---|---|
| PortOne account and the identity channel | Business registration, PortOne signup, channel enablement | Days |
| KG이니시스 통합인증 contract | Merchant contract; the CI field and, for Kakao, separate documents (P) | 1-3 weeks |
| Danal 휴대폰 본인인증 with CI, phone, foreigner flag | Merchant contract with the extra-field riders (P) | 1-3 weeks |
| CI storage approval from the agency | NICE-style CI/DI application with a security checklist (S) | Possibly weeks; ask whether the aggregator route skips it (C) |
| Counsel | CI storage, hash, retention, consent, minors (§5) | Before the first real sign-up |
Until the contract signs, the build can run on PortOne's test channel (B) so the board and the app can be finished; the first real sign-up is the gate.
5. Juniors
5.1 The law
- PIPA §22-2. Processing a child's (under 14) personal data requires the legal guardian's consent, and the service must verify that the consenter is the guardian (P: thecheck summary; the Act quoted in lane F §4.2, L: MOJ). The service may collect the minimum guardian data (name, contact) from the child without consent (PIPA §22 (5), S: same summary). Methods under the 시행령 §17-2 include marking consent on the site and confirming it by SMS to the guardian's phone (S: thecheck); other listed methods, including the guardian's phone verification and card data, appear in practice guides (S: search result summaries). I could not read the decree text (C). A terms-of-service ban on under-14 without an actual age check is called an operating risk (S: thecheck); a fine of 50 million KRW for missing guardian consent is cited by one blog (S, unverified).
- 본인확인 for under 14. Phone verification returns the line owner. A child on a parent's line verifies as the parent and looks like an adult, so the verification cannot be the age gate for under-14s; it proves the line holder only. A child with their own line, opened under a guardian's name, verifies as the guardian too (B, and the carrier path above: lines for minors are opened through a guardian, S: ajd). Samsung's own shareholder FAQ for under-14 uses a general-purpose certificate for the child and a separate verification plus consent from the guardian, in a web browser only (S: dividend.samsung.com). So a proper under-14 path is guardian-driven, not child-driven.
- Paying minors (14-18). Civil Act §5: a minor needs the guardian's consent to a legal act, and an act without it can be cancelled; adulthood is 19 (S: korea.legal §5, lawtalk). The burden of proving consent is on the party relying on the act (S, lawtalk). For us that means a card payment by a 17-year-old is cancellable by the parent, and the club may have to refund. PG rules for minors' card or transfer payments: I found nothing first-party (C: ask the PG, and the PortOne PG contract). Lane F's F4 stays open.
- Youth protection and DMs with adults. I did not retrieve any first-party text. Background: the 아동·청소년의 성보호에 관한 법률 and 정보통신망법 duties on harmful-media and grooming risk make an adult-to-minor private channel the main exposure for a community app (B, C). The repo's controls should be checked: if there is any direct messaging or friend request surface, a minor's profile should not receive adult-initiated contact outside a shared club (C: counsel; code check owed, not done here).
5.2 Practice
I found no first-party policy from the Korean sports and club apps. The general market practice, per the sources I could read, is: 14+ only with a terms ban, or a guardian-consent flow with the guardian's phone verification (S: thecheck). I will not assert what 아이엠그라운드 or 플랩풋볼 do (not found).
5.3 Today's code (the truth for behaviour)
- The wizard collects a self-reported birth year;
computeAge(birthYear) < 14atonboarding-wizard-screen.tsx:134showsOnboardingStepUnder14Gate(:352), hides the CTA, and blocks the consent step (:302). Back returns to the birth-year step (:366). The gate has no guardian path and no copy besidest().onboarding.under14. - After the redesign the birth date comes from the 본인인증, so the gate becomes real but only for adult-line users (see §5.1: a child on a parent's line verifies as the parent). This is a limit the owner should hear: the verified gate protects against honest 13-year-olds with their own line (if any), not against a child using a parent's phone. The board's
vi-u14frame (a stop, only 로그아웃) matches the stop-now decision.
5.4 Staged path
Now (launch).
- Under 14: stop. No profile, no data kept beyond what is needed to refuse; sign out (the shipped behaviour, the board frame
vi-u14). Reason: PIPA §22-2 needs a guardian-verified flow we have not built, and the 본인인증 of a child cannot be trusted as an age check. - 14 to 18: allowed, money limited.
- Verified birth date gives the age; no extra verification.
- Card (PortOne) rail blocked under 19; the manual transfer rail stays (the club's 총무 confirms, outside our payments), so a junior can still pay dues in a club that allows it. The 총무 carries the cancellation risk of Civil Act §5 (C: counsel: is a transfer to a 총무 a "legal act" we must warn about?).
- No private contact with adults outside a shared club (C), and the profile visibility is the existing face/privacy canon.
- A guardian-consent checkbox is not added; PIPA's guardian consent is for under 14 (S). Counsel to confirm that 14 to 18 does not need a guardian for our data uses.
- The age rules live in one config (policy numbers config-driven, per our memory):
minAge=14,payAge=19.
Later (expand).
- Guardian-managed junior profile under a verified parent's account: the parent (a verified adult with a CI) creates a junior with name and birth year only; the parent gives the PIPA §22-2 consent, verified by their own 본인인증; the junior has no login and no direct contact; clubs see the junior on a roster; scores and attendance are attributed to the junior profile.
- Club-registered juniors with no own login: a 총무 adds a junior with a guardian's phone for consent by SMS (S: the 시행령 method above). Requires the guardian's consent record per junior and an audit trail (C).
- Each later step is added by an axis in existing config, not a new flow (the canon rule on policy axes).
5.5 Everything that needs counsel
- Storing CI: basis, retention, hash and key, consent wording (§2.1).
- Whether the aggregator route needs the agency's CI/DI service approval (§4.4).
- Under-14: the exact 시행령 §17-2 methods and the fine exposure; whether holding a refused user's birth year is lawful.
- 14 to 18: whether a guardian's consent is needed for our data uses; Civil Act §5 risk on manual-rail dues; PG rules for minors' payments.
- Youth protection duties and adult-to-minor contact for a community app.
- Whether 본인인증 at sign-up fits PIPA data minimisation (we collect name, birth date, gender, phone, CI where the earlier flow collected only a year).
6. Questions for the owner (few, concrete)
- J1. Confirm the staged path: under 14 stops now; 14 to 18 allowed with card payments blocked under 19.
- J2. Primary channel KG이니시스 통합인증 through PortOne, fallback Danal phone verification; start both quote requests this week, because price and timing are unknown. Agree?
- J3. Are you willing to launch with the verified gate known to pass a child using a parent's phone? (My advice: yes, with the guardian-managed junior profile as the later fix.)
- J4. Show Kakao in the verification list? Its CI needs separate documents (P); I recommend leaving it off at first.
7. Implementation
- [ ] Request quotes and contract terms from PortOne (identity channel), KG이니시스 (통합인증) and Danal: unit price, tiers, billable attempt, CI/DI/foreigner/phone fields, CI storage rules. Run the three-method same-CI test (§2.2) before launch.
- [ ] Counsel pass on §5.5 before the first real sign-up.
- [ ] Migration:
verified_identitiesas in lane F §5 (hashed CI with a unique constraint, name, birth date, gender, phone, nationality,verified_at, vendor), explicit GRANT, no PII in JSONB. - [ ] Edge function: the server lookup of
identityVerificationId; never trust the client result; store only onVERIFIED. - [ ] Port and adapter:
requestIdentityVerificationbehind the registry; WebView only (docs/canon/korean-market.md). - [ ] Config:
minAge=14,payAge=19; card rail blocked belowpayAgeinsessionPaymentGateState(...)(canon/payments.md). - [ ] Onboarding: replace the birth-year step with the verified result; keep
OnboardingStepUnder14Gate(packages/features/onboarding/src/) as the stop for verified age below 14. - [ ] Board
flat-v2-auth.jsx: addvi-nophone,vi-foreign,vi-14-18frames; add the "no resident number" line tovi-intro; no own method picker. - [ ] Update
docs/canon/korean-market.md(the phone-input bullet that says 본인인증 "will need a real validator") anddocs/architecture/screen-blueprint.md.
8. Sources
PortOne: 본인인증 연동하기 (V2) · 요청 파라미터 · REST V2. Toss: toss.im/tosscert · 전자인증서비스 약관. NICE and carriers: SKT/NICE/SCI consent form · NICE CI/DI request form. Law and practice: thecheck: under-14 guardian consent · i-boss · MOJ · korea.legal 민법 §5 · lawtalk · Samsung under-14 FAQ · ajd minors' phones · yellowit own-name phone · 당근 one number · lane F of review 4.