Use o AI Guardrails SDK for Java para verificar imagens em busca de conteúdo de risco em diversos cenários de moderação, incluindo pornografia, terrorismo, publicidade, códigos QR, cenas indesejáveis e logotipos.
Este SDK aceita apenas URLs de imagem (HTTP ou HTTPS, com até 2.048 caracteres). Caminhos de arquivos locais e dados binários não têm suporte direto. Use a classe ClientUploader do utilitário Extension.Uploader para enviar arquivos locais ou fluxos binários antes de passar a URL retornada.
Pré-requisitos
Antes de começar, verifique se você tem:
Dependências Java instaladas. Consulte Instalação para conferir a versão necessária do Java. O uso de uma versão diferente causa falhas nas chamadas de operação.
A classe utilitária Extension.Uploader baixada e importada em seu projeto, caso pretenda moderar imagens locais ou fluxos binários de imagem.
Escolha um modo de detecção
|
Modo |
Como funciona |
Quando usar |
|
Síncrono |
Retorna resultados imediatamente na resposta |
Necessidade de decisões em tempo real (por exemplo, bloquear uploads antes do armazenamento) |
|
Assíncrono |
Envia uma tarefa e retorna um ID de tarefa; recupere os resultados por polling ou callback |
Processamento de grandes volumes ou quando não é necessária uma decisão instantânea |
Para obter detalhes sobre os parâmetros, consulte Detecção síncrona e Detecção assíncrona e resultados.
Moderação síncrona de imagens (recomendado)
ImageSyncScanRequest envia uma solicitação de moderação síncrona e retorna resultados em tempo real.
Regiões suportadas: cn-shanghai, cn-beijing, cn-shenzhen, ap-southeast-1
Os três exemplos abaixo usam ImageSyncScanRequest e diferem apenas na forma de fornecimento da imagem.
Moderar uma imagem online
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.green.model.v20180509.ImageSyncScanRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
// Use a RAM user's credentials, not the root account's AccessKey pair.
// Load credentials from environment variables to avoid hardcoding secrets.
// AccessKey ID: System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
// AccessKey secret: System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
DefaultProfile profile = DefaultProfile.getProfile(
"cn-shanghai",
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
DefaultProfile.addEndpoint("cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
// Reuse this client instance across requests for better performance.
IAcsClient client = new DefaultAcsClient(profile);
ImageSyncScanRequest request = new ImageSyncScanRequest();
request.setAcceptFormat(FormatType.JSON);
request.setMethod(MethodType.POST);
request.setEncoding("utf-8");
request.setProtocol(ProtocolType.HTTP);
JSONObject httpBody = new JSONObject();
// Specify one or more moderation scenarios. Charges apply per scenario per image.
// For example, moderating two images for both "porn" and "terrorism" incurs four charges.
httpBody.put("scenes", Arrays.asList("porn"));
// Create one task per image. Batch requests take longer as total time equals
// the time to process the last image.
JSONObject task = new JSONObject();
task.put("dataId", UUID.randomUUID().toString());
task.put("url", "http://www.aliyundoc.com/xxx.test.jpg"); // URL-encode any special characters
task.put("time", new Date());
httpBody.put("tasks", Arrays.asList(task));
request.setHttpContent(
org.apache.commons.codec.binary.StringUtils.getBytesUtf8(httpBody.toJSONString()),
"UTF-8", FormatType.JSON);
// The server takes up to 10s to process a moderation request.
// Set the read timeout to at least 10s to avoid premature failures.
request.setConnectTimeout(3000);
request.setReadTimeout(10000);
HttpResponse httpResponse = null;
try {
httpResponse = client.doAction(request);
} catch (Exception e) {
e.printStackTrace();
}
if (httpResponse != null && httpResponse.isSuccess()) {
JSONObject scrResponse = JSON.parseObject(
org.apache.commons.codec.binary.StringUtils.newStringUtf8(httpResponse.getHttpContent()));
System.out.println(JSON.toJSONString(scrResponse, true));
int requestCode = scrResponse.getIntValue("code");
JSONArray taskResults = scrResponse.getJSONArray("data");
if (200 == requestCode) {
for (Object taskResult : taskResults) {
int taskCode = ((JSONObject) taskResult).getIntValue("code");
// Each element in "results" contains the outcome for one moderation scenario.
JSONArray sceneResults = ((JSONObject) taskResult).getJSONArray("results");
if (200 == taskCode) {
for (Object sceneResult : sceneResults) {
String scene = ((JSONObject) sceneResult).getString("scene");
String suggestion = ((JSONObject) sceneResult).getString("suggestion");
// Act on the suggestion: block, review, or pass the image.
System.out.println("scene = [" + scene + "]");
System.out.println("suggestion = [" + suggestion + "]");
}
} else {
System.out.println("Task failed: " + JSON.toJSONString(taskResult));
}
}
} else {
System.out.println("Request failed: " + JSON.toJSONString(scrResponse));
}
}
}
}
Saída esperada:
scene = [porn]
suggestion = [pass]
Moderar um arquivo de imagem local
Para imagens locais, use ClientUploader para enviar o arquivo e obter uma URL temporária. Em seguida, envie essa URL para moderação.
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.green.extension.uploader.ClientUploader;
import com.aliyuncs.green.model.v20180509.ImageSyncScanRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
DefaultProfile profile = DefaultProfile.getProfile(
"cn-shanghai",
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
DefaultProfile.addEndpoint("cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
IAcsClient client = new DefaultAcsClient(profile);
ImageSyncScanRequest request = new ImageSyncScanRequest();
request.setAcceptFormat(FormatType.JSON);
request.setMethod(MethodType.POST);
request.setEncoding("utf-8");
request.setProtocol(ProtocolType.HTTP);
JSONObject httpBody = new JSONObject();
httpBody.put("scenes", Arrays.asList("porn"));
// Upload the local image to get a temporary URL, then submit the URL for moderation.
String url = null;
ClientUploader clientUploader = ClientUploader.getImageClientUploader(profile, false);
try {
url = clientUploader.uploadFile("d:/test.jpg");
} catch (Exception e) {
e.printStackTrace();
}
JSONObject task = new JSONObject();
task.put("dataId", UUID.randomUUID().toString());
task.put("url", url);
task.put("time", new Date());
httpBody.put("tasks", Arrays.asList(task));
request.setHttpContent(
org.apache.commons.codec.binary.StringUtils.getBytesUtf8(httpBody.toJSONString()),
"UTF-8", FormatType.JSON);
request.setConnectTimeout(3000);
request.setReadTimeout(10000);
HttpResponse httpResponse = null;
try {
httpResponse = client.doAction(request);
} catch (Exception e) {
e.printStackTrace();
}
if (httpResponse != null && httpResponse.isSuccess()) {
JSONObject scrResponse = JSON.parseObject(
org.apache.commons.codec.binary.StringUtils.newStringUtf8(httpResponse.getHttpContent()));
System.out.println(JSON.toJSONString(scrResponse, true));
int requestCode = scrResponse.getIntValue("code");
JSONArray taskResults = scrResponse.getJSONArray("data");
if (200 == requestCode) {
for (Object taskResult : taskResults) {
int taskCode = ((JSONObject) taskResult).getIntValue("code");
JSONArray sceneResults = ((JSONObject) taskResult).getJSONArray("results");
if (200 == taskCode) {
for (Object sceneResult : sceneResults) {
String scene = ((JSONObject) sceneResult).getString("scene");
String suggestion = ((JSONObject) sceneResult).getString("suggestion");
System.out.println("scene = [" + scene + "]");
System.out.println("suggestion = [" + suggestion + "]");
}
} else {
System.out.println("Task failed: " + JSON.toJSONString(taskResult));
}
}
} else {
System.out.println("Request failed: " + JSON.toJSONString(scrResponse));
}
}
}
}
Moderar um fluxo binário de imagem
Se sua aplicação mantiver uma imagem na memória como um array de bytes, envie-a diretamente com uploadBytes.
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.green.extension.uploader.ClientUploader;
import com.aliyuncs.green.model.v20180509.ImageSyncScanRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
DefaultProfile profile = DefaultProfile.getProfile(
"cn-shanghai",
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
DefaultProfile.addEndpoint("cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
IAcsClient client = new DefaultAcsClient(profile);
ImageSyncScanRequest request = new ImageSyncScanRequest();
request.setAcceptFormat(FormatType.JSON);
request.setMethod(MethodType.POST);
request.setEncoding("utf-8");
request.setProtocol(ProtocolType.HTTP);
JSONObject httpBody = new JSONObject();
httpBody.put("scenes", Arrays.asList("porn"));
// Convert the binary image data to a temporary URL, then submit the URL for moderation.
// In production, pass your in-memory byte array directly instead of reading from disk.
ClientUploader clientUploader = ClientUploader.getImageClientUploader(profile, false);
String url = null;
try {
byte[] imageBytes = FileUtils.readFileToByteArray(new File("/Users/01fb4ab6420b5f34623e13b82b51ef87.jpg"));
url = clientUploader.uploadBytes(imageBytes);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
JSONObject task = new JSONObject();
task.put("dataId", UUID.randomUUID().toString());
task.put("url", url);
task.put("time", new Date());
httpBody.put("tasks", Arrays.asList(task));
request.setHttpContent(
org.apache.commons.codec.binary.StringUtils.getBytesUtf8(httpBody.toJSONString()),
"UTF-8", FormatType.JSON);
request.setConnectTimeout(3000);
request.setReadTimeout(10000);
HttpResponse httpResponse = null;
try {
httpResponse = client.doAction(request);
} catch (Exception e) {
e.printStackTrace();
}
if (httpResponse != null && httpResponse.isSuccess()) {
JSONObject scrResponse = JSON.parseObject(
org.apache.commons.codec.binary.StringUtils.newStringUtf8(httpResponse.getHttpContent()));
System.out.println(JSON.toJSONString(scrResponse, true));
int requestCode = scrResponse.getIntValue("code");
JSONArray taskResults = scrResponse.getJSONArray("data");
if (200 == requestCode) {
for (Object taskResult : taskResults) {
int taskCode = ((JSONObject) taskResult).getIntValue("code");
JSONArray sceneResults = ((JSONObject) taskResult).getJSONArray("results");
if (200 == taskCode) {
for (Object sceneResult : sceneResults) {
String scene = ((JSONObject) sceneResult).getString("scene");
String suggestion = ((JSONObject) sceneResult).getString("suggestion");
System.out.println("scene = [" + scene + "]");
System.out.println("suggestion = [" + suggestion + "]");
}
} else {
System.out.println("Task failed: " + JSON.toJSONString(taskResult));
}
}
} else {
System.out.println("Request failed: " + JSON.toJSONString(scrResponse));
}
}
}
}
Moderação assíncrona de imagens
ImageAsyncScanRequest envia uma tarefa de moderação e retorna um ID de tarefa imediatamente. Recupere o resultado por polling com ImageAsyncScanResultsRequest ou receba um callback em seu servidor.
Regiões suportadas: cn-shanghai, cn-beijing, cn-shenzhen, ap-southeast-1
Envie URLs de imagens online, arquivos de imagem locais ou fluxos binários de imagem — as mesmas fontes de imagem com suporte na moderação síncrona. O exemplo abaixo usa uma URL de imagem online.
Enviar uma tarefa de moderação assíncrona
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.green.model.v20180509.ImageAsyncScanRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import java.util.Arrays;
import java.util.Date;
import java.util.UUID;
public class Main {
public static void main(String[] args) throws Exception {
DefaultProfile profile = DefaultProfile.getProfile(
"cn-shanghai",
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
DefaultProfile.addEndpoint("cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
IAcsClient client = new DefaultAcsClient(profile);
ImageAsyncScanRequest request = new ImageAsyncScanRequest();
request.setAcceptFormat(FormatType.JSON);
request.setMethod(MethodType.POST);
request.setEncoding("utf-8");
request.setProtocol(ProtocolType.HTTP);
JSONObject httpBody = new JSONObject();
httpBody.put("scenes", Arrays.asList("porn"));
// Optional: set a callback URL to receive results when moderation completes.
// The "seed" value is used to verify the callback signature.
httpBody.put("callback", "http://www.aliyundoc.com/xxx.json");
httpBody.put("seed", "yourPersonalSeed");
// A single request can include up to 50 images; create one task per image.
JSONObject task = new JSONObject();
task.put("dataId", UUID.randomUUID().toString());
task.put("url", "http://www.aliyundoc.com/xxx.test.jpg");
task.put("time", new Date());
httpBody.put("tasks", Arrays.asList(task));
request.setHttpContent(
org.apache.commons.codec.binary.StringUtils.getBytesUtf8(httpBody.toJSONString()),
"UTF-8", FormatType.JSON);
request.setConnectTimeout(3000);
request.setReadTimeout(10000);
HttpResponse httpResponse = null;
try {
httpResponse = client.doAction(request);
} catch (Exception e) {
e.printStackTrace();
}
if (httpResponse != null && httpResponse.isSuccess()) {
JSONObject scrResponse = JSON.parseObject(
org.apache.commons.codec.binary.StringUtils.newStringUtf8(httpResponse.getHttpContent()));
System.out.println(JSON.toJSONString(scrResponse, true));
int requestCode = scrResponse.getIntValue("code");
JSONArray taskResults = scrResponse.getJSONArray("data");
if (200 == requestCode) {
for (Object taskResult : taskResults) {
int taskCode = ((JSONObject) taskResult).getIntValue("code");
if (200 == taskCode) {
// Save the task ID to poll for results later.
System.out.println("Task ID: " + ((JSONObject) taskResult).getString("taskId"));
} else {
System.out.println("Task failed: " + JSON.toJSONString(taskResult));
}
}
} else {
System.out.println("Request failed: " + JSON.toJSONString(scrResponse));
}
}
}
}
Saída esperada:
Task ID: img4hDosCHcrFk5jAMR80XWJN-1pZ@0p
Consultar resultados de moderação assíncrona
ImageAsyncScanResultsRequest recupera resultados de uma ou mais tarefas assíncronas enviadas anteriormente. Informe os IDs das tarefas retornados no momento do envio.
Regiões suportadas: cn-shanghai, cn-beijing, cn-shenzhen, ap-southeast-1
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.green.model.v20180509.ImageAsyncScanResultsRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
DefaultProfile profile = DefaultProfile.getProfile(
"cn-shanghai",
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
DefaultProfile.addEndpoint("cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
IAcsClient client = new DefaultAcsClient(profile);
ImageAsyncScanResultsRequest request = new ImageAsyncScanResultsRequest();
request.setAcceptFormat(FormatType.JSON);
request.setMethod(MethodType.POST);
request.setEncoding("utf-8");
request.setProtocol(ProtocolType.HTTP);
// Pass the task IDs returned when you submitted the asynchronous moderation request.
List<String> taskIds = new ArrayList<String>();
taskIds.add("img4hDosCHcrFk5jAMR80XWJN-1pZ@0p");
request.setHttpContent(JSON.toJSONString(taskIds).getBytes("UTF-8"), "UTF-8", FormatType.JSON);
request.setConnectTimeout(3000);
request.setReadTimeout(6000);
try {
HttpResponse httpResponse = client.doAction(request);
if (httpResponse.isSuccess()) {
JSONObject scrResponse = JSON.parseObject(new String(httpResponse.getHttpContent(), "UTF-8"));
System.out.println(JSON.toJSONString(scrResponse, true));
if (200 == scrResponse.getInteger("code")) {
JSONArray taskResults = scrResponse.getJSONArray("data");
for (Object taskResult : taskResults) {
if (200 == ((JSONObject) taskResult).getInteger("code")) {
JSONArray sceneResults = ((JSONObject) taskResult).getJSONArray("results");
for (Object sceneResult : sceneResults) {
String scene = ((JSONObject) sceneResult).getString("scene");
String suggestion = ((JSONObject) sceneResult).getString("suggestion");
// Act on the suggestion: block, review, or pass the image.
System.out.println("scene = [" + scene + "]");
System.out.println("suggestion = [" + suggestion + "]");
}
} else {
System.out.println("Task failed: " + ((JSONObject) taskResult).getInteger("code"));
}
}
} else {
System.out.println("Request failed. Code: " + scrResponse.getInteger("code"));
}
} else {
System.out.println("HTTP error. Status: " + httpResponse.getStatus());
}
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Fornecer feedback sobre resultados de moderação
Se um resultado de moderação estiver incorreto, use ImageScanFeedbackRequest para corrigi-lo. O AI Guardrails adiciona a imagem à lista de permissões ou à lista de bloqueios de imagens semelhantes com base no seu feedback. Ao enviar uma imagem semelhante posteriormente, o AI Guardrails retorna resultados consistentes com sua correção.
Para obter detalhes sobre os parâmetros, consulte /green/image/feedback.
Regiões suportadas: cn-shanghai, cn-beijing, cn-shenzhen, ap-southeast-1
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.green.model.v20180509.ImageScanFeedbackRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws Exception {
DefaultProfile profile = DefaultProfile.getProfile(
"cn-shanghai",
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
DefaultProfile.addEndpoint("cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
IAcsClient client = new DefaultAcsClient(profile);
ImageScanFeedbackRequest request = new ImageScanFeedbackRequest();
request.setAcceptFormat(FormatType.JSON);
request.setMethod(MethodType.POST);
request.setEncoding("utf-8");
request.setProtocol(ProtocolType.HTTP);
JSONObject httpBody = new JSONObject();
// suggestion: the correct label for the image.
// "pass" — the image is clean; add to whitelist
// "block" — the image is a violation; add to blacklist
httpBody.put("suggestion", "block");
// scenes: the moderation scenarios this feedback applies to.
httpBody.put("scenes", Arrays.asList("ad", "terrorism"));
httpBody.put("url", "<image-url>");
request.setHttpContent(
org.apache.commons.codec.binary.StringUtils.getBytesUtf8(httpBody.toJSONString()),
"UTF-8", FormatType.JSON);
request.setConnectTimeout(3000);
request.setReadTimeout(10000);
try {
HttpResponse httpResponse = client.doAction(request);
if (httpResponse.isSuccess()) {
JSONObject scrResponse = JSON.parseObject(new String(httpResponse.getHttpContent(), "UTF-8"));
System.out.println(JSON.toJSONString(scrResponse, true));
if (200 == scrResponse.getInteger("code")) {
System.out.println("Feedback submitted successfully.");
} else {
System.out.println("Failed. Code: " + scrResponse.getInteger("code"));
}
} else {
System.out.println("HTTP error. Status: " + httpResponse.getStatus());
}
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace();
}
}
}
Observações de uso
Faturamento: As cobranças são calculadas por imagem e por cenário. Moderar uma imagem em dois cenários gera duas cobranças.
Solicitações em lote: Ao enviar várias imagens em uma única solicitação, a latência total equivale ao tempo de processamento da imagem mais lenta. Para cargas de trabalho sensíveis ao tempo, mantenha lotes pequenos ou use solicitações individuais.
Timeout de conexão: Defina o timeout de conexão para pelo menos 3.000 ms. Para solicitações de envio síncronas e assíncronas, configure o timeout de leitura para no mínimo 10.000 ms. Para solicitações de consulta (
ImageAsyncScanResultsRequest), um timeout de leitura de 6.000 ms é suficiente.Reutilização de cliente: Instancie
DefaultAcsClientuma única vez e reutilize-o nas solicitações. Criar um novo cliente por solicitação degrada o desempenho e aumenta a sobrecarga de conexão.Credenciais: Use o AccessKey ID e o AccessKey secret de um usuário RAM em vez das credenciais da conta raiz. Armazene-os em variáveis de ambiente, não no código-fonte.