> ## Content Index
> Fetch the complete content index at: https://kr.vizney.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# 태블로 데이터 앱 게시에 필요한 권한과 관리자 승인 범위
- URL: https://kr.vizney.com/tableau-data-app-publish-permissions/
- Published: 2026-11-07T10:54:59.000Z
- Updated: 2026-11-07T11:36:08.000Z
- Author: 황예환
- Tags: Knowledge Base

[태블로 데이터 앱(Tableau Data Apps)](https://kr.vizney.com/what-is-tableau-data-apps/)은 코드로 만든 분석 웹 앱을 통합 문서에 넣어 Tableau가 호스팅하는 기능입니다. 외부 API를 부르는 앱은 관리자가 origin을 허용해야 합니다. 그래서 외부 호출 없이 `queryAsync()`만 쓰는 앱이라면 관리자 승인 없이 게시할 수 있는지, Tableau Cloud에서 처음부터 게시까지 확인했습니다.

결과적으로 외부 origin 승인 없이 게시와 실행까지 됐습니다(게시한 소유자 계정 기준). 하지만 데이터 원본의 API 액세스(API Access) 권한은 별도로 필요했습니다. Samples 프로젝트의 공용 데이터 원본은 이 권한이 없어 앱을 만들기 전 조회 단계에서 막혔고, 직접 게시한 데이터 원본으로 바꿔 진행했습니다. 따라서 "`queryAsync()`만 쓰면 승인이 필요 없다"고 일반화할 수는 없습니다.

아래에서 \[실측\]은 직접 확인한 결과, \[문서\]는 공식 문서 내용, \[추론\]은 시험하지 않은 판단입니다.

- **외부 origin:** 승인이 필요 없었습니다. 앱이 부를 수 있는 외부 origin 목록이 비어 있었고(`allowedOrigins: []`), 앱 코드에 `fetch()` 호출이 없었습니다. \[실측\]
- **데이터 원본의 API 액세스:** 필요했습니다. 공용 데이터 원본은 조회가 거부됐고, 사용자 계정으로는 권한을 부여할 수 없었습니다. \[실측\] 공식 문서도 작성자에게 데이터 원본마다 API 액세스를 요구합니다. \[문서\]
- **통합 문서 게시:** 승인 없이 게시됐습니다. \[실측\]
- **앱 실행:** 관리자 조치나 신뢰 확인 창 없이 실행됐습니다(소유자 계정). \[실측\] 데이터 앱 허용은 사이트별 설정입니다. \[문서\] 앱이 실행됐으니 이 사이트는 허용된 상태로 보이지만, 설정 화면은 확인하지 않았습니다. \[추론\]
- **다른 시청자:** 통합 문서와 데이터 원본 양쪽에 API 액세스가 필요합니다. \[문서\] 다른 계정으로는 시험하지 못했습니다.

검증 환경은 다음과 같습니다.

- **사이트:** Tableau Cloud 2026.3.3
- **제작 도구:** Claude Code, Tableau MCP, tableau-plugin(커밋 `a8febd1`)의 데이터 앱 작성 스킬
- **로컬 환경:** Windows, Python 3.14.7
- **앱 구성:** Sales·Profit 합계 KPI 2개, Region별 Sales 막대 차트, Region 필터
- **Extensions API:** 번들 라이브러리 기준 1.19.0-pre.10
- **검증일:** 2026년 11월 6일

---

### 1\. 첫 시도는 어디서 막혔나요?

앱을 만들기 전, 데이터 원본의 필드를 확인하는 단계에서 막혔습니다. 원래 대상은 Samples 프로젝트의 공용 데이터 원본 `Superstore Datasource`였습니다. Tableau MCP의 `get-datasource-metadata`는 403을 돌려줬고, `query-datasource`는 다음 오류를 돌려줬습니다.

```
The user does not have the required permissions: VIZQL_DATA_API_ACCESS to access the data source.
```

일시적인 오류인지 보려고 다시 호출했지만 같은 403이 났습니다. 사용자가 권한 부여를 시도한 뒤에도 마찬가지였고, 결국 사용자 계정으로는 API 액세스를 부여할 수 없었습니다.

이 요건은 [공식 개요 문서](https://tableau.github.io/extensions-api/docs/dataapps/trex%5Fdataapp%5Foverview?ref=kr.vizney.com)의 작성자 조건에 "View, Connect and API access to each published data source the data app uses"로 적혀 있습니다. 그런데 플러그인의 사전 점검 항목(사이트 역할, 게시 권한, 도구 호출 가능 여부)에는 데이터 원본 권한이 없습니다. 게시 요약 스크립트도 API 액세스를 시청자(Viewers) 조건으로만 안내합니다. 그래서 이 요건은 게시 단계가 아니라 첫 조회 단계에서야 드러났습니다. 데이터 앱을 만들기 전에 대상 데이터 원본에서 메타데이터 조회가 되는지 먼저 확인하는 편이 좋습니다.

---

### 2\. 권한을 받을 수 없을 때는 어떻게 진행했나요?

사용자가 default 프로젝트에 직접 게시한 데이터 원본 `Superstore_YH`로 바꿔 진행했습니다. 같은 도구로 메타데이터 조회와 쿼리가 성공했고, 21개 필드 중 `Sales`, `Profit`, `Region`을 썼습니다. 직접 게시한 데이터 원본이라 소유자로서 API 액세스가 있는 것으로 보이지만, 권한 규칙을 따로 확인하지는 않았습니다. \[추론\]

원래 요구한 데이터 원본과 다르므로, 이 글의 게시와 동작 결과는 모두 `Superstore_YH` 기준입니다. 권한을 우회하는 방법은 쓰지 않았습니다. 임베드된 데이터 원본 조회, 통합 문서 다운로드, 필드 추정, 파일 데이터 원본 대체가 여기에 해당합니다.

---

### 3\. 게시까지 어떤 단계를 거쳤나요?

데이터 원본을 바꾼 20:32:58부터 게시를 마친 20:40:20까지 7분 22초가 걸렸습니다. 시작부터 게시까지는 권한 문제로 멈춘 시간을 포함해 약 31분입니다.

- **작업 공간 생성:** `scaffold-data-app`이 성공했고, 외부 origin 목록은 비어 있었습니다(`allowedOrigins: []`). 그래서 앱은 외부 호출 없이 `queryAsync()`만 쓰고, 차트도 라이브러리 없이 직접 그렸습니다.
- **계획 적용:** Windows에서 `apply_plan.py`가 정상 경로도 경로 이탈로 판정해 실패했습니다. 한 줄을 고친 사본으로 진행했고, 이 문제는 [tableau/tableau-plugin#35](https://github.com/tableau/tableau-plugin/issues/35?ref=kr.vizney.com)로 제보했습니다. 오류 원문과 수정 내용은 [태블로 데이터 앱 제작 중 권한·스크립트·게시 오류 해결하기](https://kr.vizney.com/tableau-error-data-app/)에 정리했습니다.
- **데이터 원본 연결:** `wire_datasource.py`로 `Superstore_YH`를 연결했습니다.
- **사전 확인:** Tableau MCP의 `query-datasource`로 앱과 같은 형태의 쿼리를 먼저 실행해 값을 확인했습니다. 전체 Sales 합계는 2,326,534.35, Profit 합계는 292,296.81입니다.
- **패키징:** `package_twbx.py`가 경고 없이 74,443바이트 .twbx를 만들었습니다.
- **게시:** `publish-workbook`의 파일 경로 방식(`workbookFilePath`)은 거부됐습니다. `request-workbook-upload`로 업로드 주소를 받아 파일을 올린 뒤, `workbookUploadId`로 게시해 `status: "published"`, `warnings: []`를 받았습니다. 플러그인 문서가 예상한 분기입니다.

---

### 4\. 게시한 앱은 실제로 동작했나요?

로그인한 브라우저에서 게시 소유자 계정으로 열어 보니, KPI, 막대 차트, Region 필터가 실시간 데이터로 동작했습니다.

다만 게시 직후 Tableau MCP의 `get-view-image`로 확인한 결과는 믿을 수 없었습니다. 이 도구는 오류 없이 PNG(40,604바이트)를 돌려줬지만, 이미지 내용은 "Sign in to Tableau Cloud" 화면이었습니다. 원인은 모릅니다. 같은 뷰가 로그인한 브라우저에서는 정상으로 보였으므로 앱 문제로 볼 근거는 없습니다. 성공 응답만으로 동작을 판단하지 않는 편이 좋습니다.

화면 값은 사전 확인 값과 같았습니다.

- **전체:** Sales 합계 2,326,534, Profit 합계 292,297
- **Region별 Sales:** West 739,814, East 691,828, Central 503,171, South 391,722
- **East 선택:** Sales 691,828, Profit 94,883, 막대 1개

![Region 필터에서 East를 고른 데이터 앱 화면. KPI가 Sales 691,828, Profit 94,883으로 바뀌고 East 막대 하나만 남았다.](https://storage.ghost.io/c/71/f6/71f6ee37-5711-4588-b703-c29372b31c0a/content/images/2026/11/live-filter-east-crop.jpg)

- **쿼리 경로:** `queryAsync()`는 같은 호스트의 `POST /api/v1/vizql-data-service/query-datasource`로 나갔습니다. 페이지를 열 때마다 3건(Region 목록, 합계, Region별 Sales)이 나갔고 모두 HTTP 200이었습니다. \[실측\]
- **콘텐츠 보안 정책:** 응답 헤더는 아래와 같으며, 외부 origin이 없습니다. `<pkg>`는 앱 패키지의 `content/` 경로입니다. \[실측\]

```
default-src <pkg>; img-src data: <pkg>; font-src data: <pkg>; script-src 'unsafe-inline' <pkg> 'unsafe-eval'; style-src 'unsafe-inline' <pkg>; frame-src 'none'; object-src 'none'; sandbox allow-scripts allow-popups allow-popups-to-escape-sandbox
```

- **샌드박스:** 앱 프레임에 `allow-same-origin`이 없어, 문서의 origin `null` 설명과 맞습니다. \[실측\]
- **신뢰 확인 창:** 나타나지 않았습니다. 플러그인 문서는 처음 열 때 나타날 수 있다고 안내하며, 다른 사용자에게도 나타나지 않는지는 모릅니다.
- **키보드 조작:** 화살표 키로 필터를 East로 옮길 때 쿼리가 4건 나갔습니다. Central을 거칠 때도 변경 이벤트가 발생한 것으로 보입니다. 오류는 아니지만, `<select>` 필터를 쓰는 앱이라면 고려할 부분입니다.

![Central 막대에 마우스를 올리자 'Central / Sales 503,171' 툴팁과 행 강조가 나타난 화면.](https://storage.ghost.io/c/71/f6/71f6ee37-5711-4588-b703-c29372b31c0a/content/images/2026/11/live-tooltip-crop.jpg)

외부 호출이 없어도 API 액세스가 필요했던 이유는 `queryAsync()`가 VizQL 데이터 서비스를 호출하기 때문입니다. [Tableau 도움말](https://help.tableau.com/current/server/ko-kr/permissions%5Fcapabilities.htm?ref=kr.vizney.com)은 API 액세스를 "VizQL 데이터 서비스를 통해 통합 문서의 데이터 원본을 쿼리"할 수 있게 하는 권한으로 설명합니다.

확인하지 못한 부분도 있습니다.

- **다른 시청자:** 게시 요약 스크립트는 아래와 같이 안내했습니다. 공식 문서도 시청자에게 통합 문서의 보기·전체 데이터 쿼리·API 액세스와 데이터 원본의 보기·연결·API 액세스를 요구합니다. 다른 계정으로는 시험하지 못해, API 액세스가 없는 계정에서 앱이 어떻게 실패하는지는 확인하지 못했습니다.

```
Some viewers may not be able to view this data app. Missing workbook permissions:
- Unnamed group: API Access
Viewers also need API Access on the published data source "Superstore_YH".
```

- **로딩·빈 결과·오류 상태:** `tableau` 객체를 흉내 낸 mock 환경에서만 시험했습니다.
- **API 버전:** 샌드박스 때문에 런타임 값을 읽지 못했고, 번들 라이브러리 기준 1.19.0-pre.10입니다.

실무에서는 시작 전에 대상 데이터 원본의 메타데이터 조회가 되는지 확인하고, 공유 전에 통합 문서와 데이터 원본의 API 액세스를 시청자 그룹 기준으로 점검한 뒤, 권한이 제한된 계정으로 앱을 직접 열어 보는 편이 좋습니다.

---

### Note:

이번 포스트는 2026년 11월 6일 Tableau Cloud(2026.3.3)에서 진행한 검증과 2026년 11월 7일 기준 Tableau 공식 문서를 바탕으로 작성되었습니다. 베타 기간 중 기능과 요건이 변경될 수 있습니다.