본문으로 건너뛰기
Paul's Dev Notes

Scoped Application vs Global 권한 경계 — Cross-Scope Privilege, Public Script Include, Wildcard ACL 제약

ServiceNow Scoped Application 이 Global scope 자원에 접근할 때의 권한 경계, Cross-Scope Privilege 의 Runtime access(Tracking/Enforcing) 메커니즘, Script Include Accessible from 옵션, Scoped App 의 wildcard ACL 제약, 이관 시 global side 권한 누락 함정.

검증 인스턴스: OOTB Australia · 검증일 2026-05-28

개요

Scoped Application(스코프드 애플리케이션)은 단순한 폴더 구분이 아니다. x_<vendor>_<app> 형식의 namespace권한 경계 두 가지를 동시에 제공하는 개발 단위다. 같은 이름의 테이블·스크립트·비즈니스 룰이 Global scope 와 충돌하지 않는 이유는 namespace 격리이고, Scoped App 코드가 Global 자원을 자유롭게 호출하지 못하는 이유는 권한 경계 때문이다. 이 두 속성을 분리해 이해하지 않으면 cross-scope 이슈 디버깅이 방향을 잃는다.

Scoped App 이 Global scope 자원(테이블, Script Include 등)에 접근하려면 명시적 권한이 필요하다. ServiceNow 는 이 접근 시도를 sys_scope_privilege 테이블에 레코드로 자동 생성해 추적한다. Runtime access 상태(Tracking / Enforcing / Disabled)가 이 레코드를 실제 권한 게이트로 만들지 추적 로그로만 남길지를 결정한다. 개발 환경에서는 Tracking 으로 열려 있다가 App 이 설치될 때 Enforcing 으로 전환되는 것이 일반적인 동작이어서, 개발 중 문제없이 동작하던 cross-scope 호출이 운영 인스턴스에서 갑자기 차단되는 현상으로 이어질 수 있다.

이 글에서 다루는 두 가지 추가 함정도 중요하다. 첫째, wildcard ACL(*)은 Global scope 에서만 사용할 수 있고 Scoped App 에서는 사용이 불가하다 — Scoped App 에서의 ACL 패턴은 명시적 테이블명을 써야 한다. 둘째, Scoped App 을 Update Set 이 아닌 Application file 로 이관할 때 Global scope side 의 변경(테이블의 “Application Access” 토글 등)이 자동으로 포함되지 않아 target 인스턴스에서 권한이 끊기는 함정이 있다.

OOTB(Out-of-the-Box, 기본 제공) Australia 기준입니다. Cross-Scope Privilege 의 Runtime access 전환 동작, glide.sm.default_mode property 의 적용 범위는 인스턴스 버전 및 관리자 정책에 따라 달라질 수 있습니다.


§1 — Scope 의 정의와 namespace

ServiceNow 의 Global scope 는 플랫폼의 OOTB 기본 scope 다. ITSM 코어 테이블(incident, change 등), 대부분의 OOTB Script Include, 기본 ACL 레코드가 모두 Global scope 에 속한다. sys_scope 필드 값이 global 이면 해당 레코드는 Global scope 소속이다.

Scoped Application 은 별도 namespace 를 가진 격리 단위다. App 생성 시 x_<vendor>_<app> 형식의 prefix 가 부여되고, 이 App 이 소유하는 테이블·스크립트·UI 요소는 모두 이 prefix 를 달고 sys_scope 가 해당 App 의 sys_id 를 가리킨다. Scoped App 안에서 생성한 sys_scope_privilege 레코드도 이 App 의 scope 에 묶인다.

신규 커스텀 개발에 Scoped Application 이 권장되는 이유는 namespace 충돌 방지와 Source Control(Git) 연동 친화도 때문이다. Global scope 에 직접 커스텀 코드를 쌓으면 OOTB 업그레이드 시 충돌 위험이 높아지고, Git 기반 팀 협업이 어려워진다.


§2 — Cross-Scope Privilege 자동 생성 + Runtime access

Scoped App 코드가 Global scope 의 테이블이나 Script Include 에 접근할 때, ServiceNow 플랫폼은 그 접근 시도를 sys_scope_privilege 테이블에 레코드로 자동 생성 한다. 이 레코드에는 접근 주체(Scoped App), 접근 대상(Global 자원), 그리고 Runtime access 상태가 기록된다. 개발자가 직접 생성할 필요 없이 코드 실행 시 자동으로 만들어지는 것이 핵심이다.

Runtime access 의 3 상태:

  • Tracking: 접근 시도를 기록하되 차단하지 않는다. 개발·탐색 단계에서의 기본 동작이다. 어떤 cross-scope 접근이 발생하는지 파악하는 데 활용된다.
  • Enforcing: 권한이 명시적으로 부여된 접근만 허용하고, 그 외는 차단한다. 운영 환경의 일반적인 상태다.
  • Disabled: 해당 privilege 레코드 자체를 비활성화한다. 접근 추적과 차단 모두 동작하지 않는다.

중요한 동작 패턴이 있다. Scoped App 을 다른 인스턴스에 설치 할 때, Tracking 상태였던 sys_scope_privilege 레코드가 Enforcing 으로 자동 전환되는 것이 일반적인 동작이다. 이 전환이 개발 환경과 설치 환경 간 동작 차이를 만든다 — 개발 인스턴스에서는 Tracking 이라 통과됐던 cross-scope 호출이 설치 후 Enforcing 에서 차단되는 시나리오다. 인스턴스 정책과 버전에 따라 전환 동작이 다를 수 있으므로, App 이관 전 sys_scope_privilege 레코드의 상태를 반드시 확인하는 것이 권장된다.

Scoped App CodeGlobal 자원 호출Global 자원 접근 시도table / Script Include자동 생성sys_scope_privilege레코드 자동 생성·추적Runtime access 상태Tracking — 기록만, 차단 없음Enforcing — 미허용 접근 차단Disabled — 추적·차단 모두 OffApp 설치 시 Tracking → Enforcing 전환

Global 자원 중 Script Include 는 별도 설정(“Accessible from” 옵션)으로 cross-scope 가시성을 제어한다. sys_scope_privilege 를 통해 접근 권한이 있더라도, Script Include 자체가 “This application scope only” 로 설정돼 있으면 호출이 차단된다. 두 레이어가 독립적으로 존재함을 기억해야 한다.


§3 — Script Include “Accessible from” 옵션

Script Include 는 sys_scope_privilege 레코드 레이어와 별개로, 레코드 자체의 “Accessible from” 필드로 cross-scope 가시성을 제어한다. 옵션은 두 가지다.

This application scope only

기본값(default). 해당 Script Include 를 소유한 scope 안에서만 호출 가능. 다른 Scoped App 또는 Global 에서 호출 시 차단된다. 가장 보수적이고 안전한 설정이다.

All application scopes

모든 scope 에서 호출 가능한 public Script Include. 다른 Scoped App 이나 Global scope 에서 이 Script Include 를 참조할 수 있다. 공유 유틸리티 함수처럼 명시적으로 public API 를 제공할 때 사용한다.

sn_ prefix 관례: cross-scope 호출용 Script Include 클래스명에 sn_ prefix 를 붙이는 팀 컨벤션이 일반적이다. 플랫폼 강제 규칙이 아니므로 팀 정책에 따라 달라진다.

“All application scopes” 로 설정하면 Script Include 는 플랫폼 전체에 공개 API 로 노출된다. 변경 시 다른 scope 의 의존성이 깨질 수 있으므로, public Script Include 는 의존성 그래프를 함께 추적해야 한다.


§4 — Wildcard ACL * 제약

ACL(Access Control List, 접근 제어 목록)의 wildcard * 패턴은 Global scope 전용 이다. Scoped App 에서 ACL 을 생성할 때 Name 필드에 * 또는 *.* 를 사용할 수 없다. Global scope 에서 *.* 는 “플랫폼 전체 모든 테이블·필드”에 적용되는 가장 넓은 패턴이지만, Scoped App 은 이 wild-card 형태의 범용 ACL 을 소유할 수 없다.

Scoped table 의 ACL 패턴은 <table>.None 또는 <table>.* 와 같이 명시적 테이블명을 기반으로 작성된다. <table>.None 은 테이블 권한의 진입점 — ACL 평가 순서 글 에서 다룬 Phase 1 table-level ACL 에 해당하며, 이 phase 를 통과해야 record·field phase 가 순서대로 평가된다.

glide.sm.default_mode property 는 wildcard ACL 의 비-admin 접근 제한을 enforce 하는 플랫폼 설정이다. 이 property 가 deny 모드로 설정되면 *.* 패턴 ACL 이 admin 이 아닌 사용자에게 적용되는 방식이 제한된다. 정확한 동작은 인스턴스 버전과 구성에 따라 다를 수 있으므로, 적용 전 해당 인스턴스에서 직접 검증이 필요하다.

Scoped App 에서 wildcard 를 쓸 수 없다는 점이 Global scope 과의 가장 큰 ACL 설계 차이다. Scoped App 의 보안 경계는 wildcard 대신 명시적 테이블·필드명 기반 ACL 로 구성해야 한다.


§5 — 이관 시 권한 누락 함정

Scoped Application file(.app 내보내기 또는 Source Control 을 통한 배포)은 일반적으로 해당 App scope 안에 속한 sys_scope_privilege 레코드를 포함한다. cross-scope 접근에 필요한 privilege 레코드가 App 파일과 함께 target 인스턴스로 이동하는 것이 통상적인 동작이다. 단, 인스턴스와 버전에 따라 포함 범위가 다를 수 있으므로, 이관 후 sys_scope_privilege 테이블에서 해당 App 의 레코드 목록을 직접 확인하는 것이 권장된다.

반면 Global scope side 의 변경은 App file 에 포함되지 않는다. 대표적인 예가 테이블의 “Application Access” 설정이다. Global 테이블의 Application Access 토글(Scoped App 의 read/create/write/delete 허용 여부)을 개발 인스턴스에서 변경했다면, 이 변경은 Scoped App file 이 아닌 별도 Global Update Set 에 캡처해야 한다. Target 인스턴스에서 App file 만 배포하면 Global side 변경이 누락되어 cross-scope 접근이 차단된다.

실전 체크 순서는 다음과 같다:

  1. Target 인스턴스의 sys_scope_privilege 테이블에서 해당 App 의 레코드를 조회 — state 가 Requested 로 남아 있으면 권한이 아직 부여되지 않은 상태
  2. Global scope 의 Application Access 설정이 source 인스턴스와 일치하는지 확인
  3. Global scope side 변경이 있었다면, 별도 Global Update Set 을 함께 이관

Update Set vs Application 이관 모델 글 에서 다룬 두 이관 모델의 차이 — Update Set 은 변경 레코드 단위, App file 은 scope 단위 — 가 이 함정의 근원이다. App file 이 “내 scope 의 것” 만 담기 때문에, Global scope 에 가한 변경은 별도 캡처가 필요하다.


§6 — 권장 패턴 체크리스트

Scoped App 적합 케이스

재배포·다중 인스턴스 배포, Git 기반 협업, 네임스페이스 격리가 필요한 커스텀 기능. 신규 개발은 가능하면 Scoped App 으로 시작하는 것이 ServiceNow 권장 방향이다.

Global scope 적합 케이스

OOTB 자원의 직접 수정(테이블 컬럼 추가, 기존 Business Rule 수정), 긴급 패치처럼 scope 설계 비용이 과도한 소규모 수정. Wildcard ACL 이 필요한 플랫폼 전체 보안 정책.

Cross-Scope 의존성 최소화

sys_scope_privilege 레코드가 많아질수록 App 의 이식성이 낮아진다. Global 자원 호출을 wrapper Script Include 로 집중시키고, 의존성 목록을 App 개발 초기부터 관리하는 것이 유지보수 비용을 낮춘다.

이관 전 글로벌 side 확인

App file 이관 전 Global scope 에서 변경한 Application Access, ACL, 공유 Script Include 설정을 별도 Global Update Set 으로 캡처했는지 체크. Target 에서 sys_scope_privilege state=Requested 레코드 존재 여부를 배포 후 바로 검증.


참조